@youmych

Как добавить информацию о контексте в прграмму с исключениями?

Для примера код:

// исключение, сообщающее об ошибке в формате заголовка файла
class incorrect_header_format : public std::runtime_error
{
public:
    incorrect_header_format() : std::runtime_error("Invalid header") {}
};
// функция, которая читает заголовок файла и разбирает его.
// выбрасывает исключение если формат не подходит
void parse_header(std::istream& input)
{
     header_t header;

     if( input.read( &header, sizeof(header) ) { 
            throw incorrect_header_format();      // (1)
     }
      // разбор полей заголовка
      // ...
      if( header_values_incorrect ) 
           throw incorrect_header_format();      // (2)     
}
// функция открывает файл path и разбирает его в соответствии с алгоритмом обработки.
// в случае ошибок открытия или ошибок формата кидает исключения
void open_and_parse(const std::string& path)
{
    std::ifstream input(path);
    if( !input ) {
          std::stringstream msg;
          msg << "Can't open file " << path;
          throw std::runtime_error( msg.str() ); // (3)
    }

     parse_header(input);
     parse_data(input);
}


int main(int argc, char** argv)
{
    try {
       for(int i = 1; i < argc; ++i) {
           open_and_parse( argv[i] );
       }
    }
    catch(std::exception& e) {
        std::cerr << "Caught exception: " << e.what() << std::endl; // (4)
    }
    return 0;
}


Проблема в том что при таком подходе внутри функции parse_header() теряется информация о том какой файл обрабатываем. Соответственно не получается сформировать текст сообщения в (1) и (2) подобно тому как это делается в (3). То есть хочется чтобы при выводе исключения в (4) формировалось что-то вроде :

Caught exception: Invalid header in file /path/to/file

Не хочется оборачивать в try-catch код внутри open_and_parse(), хотя это может решить проблему. Может есть какие-то другие способы сделать красиво?
Мне даже (3) не особо нравится т.к. непонятно по каким причинам файл нельзя открыть: то ли он не существует, то ли у процесса нет доступа то ли еще что.
  • Вопрос задан
  • 24 просмотра
Пригласить эксперта
Ответы на вопрос 1
@kn0ckn0ck
Продюсер
Ну так этим конструктором ты затыкаешь ему рот, а нужно принимать строку и передавать ее предку:
incorrect_header_format() : std::runtime_error("Invalid header") {}

Далее при использовании исключения incorrect_header_format передавай имя файла в конструктор, ровно так как ты это делаешь здесь:
throw std::runtime_error( msg.str() ); // (3)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы