我对异常处理的理解非常有限。虽然我发现抛出异常很容易(或者我可以将其打包以expected<T>
备后用),但我对如何处理异常知之甚少。
目前我的知识仅限于
清理我自己的资源并重新抛出要在适当位置处理的异常。例如
ptr p = alloc.allocate(n); try { uninitialized_copy(first,last,p);//atomic granularity, all or none } catch(...) { alloc.deallocate(p,n); throw; }
但我想,这可以等效地转换为RAII
模式
alloc_guard<ptr> p{alloc.allocate(n)};
uninitialized_copy(first,last,p.get());
p.commit();
在顶层捕获异常,撰写并打印一条好消息并退出。例如
int main(int argc,char** argv) { try { app_t the_app(argc,argv); the_app.run(); } catch(std::runtime_error& e) { //instead of what, I can also compose the mesage here based on locale. std::cout<<e.what()<<std::endl; } }
因此,我所做的只是在顶级函数中,例如main
捕获异常并打印适当的消息并关闭。
在使用各种外部库作为实现的后端来实现具有一组很好的 API 的库时,我意识到第三方库异常是我的 API 规范的一部分,因为它们跨越了我的库边界并进入了用户代码!
因此,我的库 API 将我正在使用的外部库(并且每个库都有自己的异常层次结构)中的所有异常泄露给了用户代码。
这引出了我的问题,当我发现任何异常时可以做什么?
进一步来说,
- 我可以将捕获的异常从外部库转换为我自己的异常并以通用方式抛出它(比如第三方库异常层次结构和我的异常 API 之间的映射作为 a 提供
mpl::map
)? - 我可以做一些比打印消息/调用堆栈更有用的事情吗,比如使用不同的输入参数在 throw 站点恢复函数(比如当我得到 a
file_not_found
or时disk_error
,使用不同的文件重新运行函数)? - 还有其他值得了解的模式吗?
谢谢