Y
Y
youmych2018-02-08 23:18:47
Software design
youmych, 2018-02-08 23:18:47

How to add context information to a program with exceptions?

For example code:

// исключение, сообщающее об ошибке в формате заголовка файла
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;
}

The problem is that with this approach, inside the parse_header() function, information about which file is being processed is lost. Accordingly, it is not possible to form the message text in (1) and (2) in the same way as it is done in (3). That is, I want something like:
Caught exception: Invalid header in file /path/to/file to be formed when an exception is thrown in (4)
. Maybe there are some other ways to make it beautiful?
I don't even like (3) much. it is not clear for what reasons the file cannot be opened: either it does not exist, or the process does not have access, or something else.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
K
kn0ckn0ck, 2018-02-09
@kn0ckn0ck

Well, with this constructor you shut up his mouth, but you need to take a string and pass it to the ancestor:
Further, when using the incorrect_header_format exception, pass the file name to the constructor, exactly as you do here:
throw std::runtime_error( msg.str() ); // (3)

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question