提升异常的错误信息

luc*_*nte 7 c++ boost exception

使用时boost::exception,了解异常所携带的数据的首选方法是什么?在boost文档中,给出了以下示例:

catch( io_error & e )
    {
    std::cerr << "I/O Error!\n";

    if( std::string const * fn=get_error_info<file_name>(e) )
        std::cerr << "File name: " << *fn << "\n";

    if( int const * c=get_error_info<errno_code>(e) )
        std::cerr << "OS says: " << strerror(*c) << "\n";
    }
Run Code Online (Sandbox Code Playgroud)

这似乎有点尴尬,特别是如果异常冒泡了很多层并且理论上可以获得大量元数据.因此,我认为记录每个异常类的可能错误信息是有意义的.然后我可能还需要一些函数的文档,关于异常中可能包含的信息.最后我觉得我在文档中有完全相同的结构,就像我在代码中使用的那样,如果我只使用类似下面的结构:

struct FileException {
  string* filename; // NULL or string
}
Run Code Online (Sandbox Code Playgroud)

然后我可以在catch块中更改此信息:

catch (FileException& e) {
  e.filename = filename;
  throw;
}
Run Code Online (Sandbox Code Playgroud)

这种简单的方法可以解决大部分文档,并从所有安全性中获益(例如,不尝试从中获取文件名MathException).然而人们使用提升.我缺少动态方法的一大优势吗?如何记录代码中的错误信息?

Big*_*oss 0

如果您可以更改或设计异常以包含描述错误所需的内容,请按照您的意愿进行操作。但是如果您的代码没有生成异常,或者您在生成错误时无法访问错误信息,那么您需要error_info. 例如,我们有一个read自由函数,可以从不包含文件名的 C++ 文件对象中读取数据,如下所示:

void read( file& fp, std::vector<unsigned char>& buf ) {
    if( fread(&buf[0], 1, buf.size(), fp.getFile()) == -1 ) {
        // I don't know the file name, what should I do here??
        boost::throw_exception( io_error() );
    }
}

try {
    file fp( "/path/to/file" );
    // do some thing with fp
    read( fp, buffer );
} catch( io_error& e ) {
    e << file_name( "/path/to/file" ); // here I can provide file name
    throw;
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,error_info设计的目的是我必须增量地将数据添加到错误中,但是如果在抛出站点上我拥有所有必需的信息,那么我可以将这些信息嵌入到异常类中并避免使用error_info