如何为多处重复catch逻辑创建统一错误处理器并存放至main.cpp
实现方案
你可以选择两种方案实现通用异常处理,分别适配不同的业务场景:
方案1:异常全链路透传到main统一处理
适合异常发生后不需要继续执行后续任务、直接终止程序的场景。
步骤1:清理task.cpp冗余代码
移除所有重复的try/catch块,核心业务逻辑直接暴露,异常自动沿调用栈向上透传:
// 改造后task.cpp中的代码,无需手动捕获异常 if (!stack.parseAndAnalyze(src.first, src.second)) successful = false; else stack.optimize();
如果原来的函数返回值仅用于标识异常场景,可直接改为无返回值,正常执行完成就继续,异常发生后直接透传。
步骤2:修正main.cpp的异常捕获逻辑
首先修复原有代码的语法错误:C++不支持单个catch子句用||捕获多个异常类型,同时调整catch顺序为从具体类型到泛化类型,避免异常被提前拦截:
// 可先提取公共打印逻辑,减少重复代码 void printExceptionInfo(std::exception const& e, std::string const& prefix = "Uncaught exception") { cerr << prefix << (e.what() ? ": " + std::string(e.what()) : ".") << endl; } int main(int argc, char** argv) { try { setDefaultOrCLocale(); solidity::frontend::CommandLineInterface cli(cin, cout, cerr); if (!cli.parseArguments(argc, argv) || !cli.readInputFiles() || !cli.processInput() || !cli.actOnInput()) return 1; return 0; } catch (InternalCompilerError const& _exception) { cerr << "Uncaught exception" << boost::diagnostic_information(_exception) << endl; return 1; } catch (smtutil::SMTLogicError const& _exception) { cerr << "Uncaught exception" << boost::diagnostic_information(_exception) << endl; return 1; } catch (boost::exception const& _exception) { cerr << "Uncaught exception" << boost::diagnostic_information(_exception) << endl; return 1; } catch (Exception const& _exc) { printExceptionInfo(_exc, "Failed to import AST: "); return 1; } catch (std::exception const& _e) { printExceptionInfo(_e); return 1; } catch (...) { cerr << "Uncaught exception" << endl; return 1; } }
如果需要区分不同场景的异常提示(比如汇编器、AST导入等),可以在自定义异常类型中增加scene字段,抛出异常时赋值,捕获后读取该字段拼接提示信息即可。
方案2:通用包装函数实现task层统一处理
适合单任务失败后需要继续执行其他任务、无需终止整个程序的场景,无需改动现有调用逻辑和返回值设计。
步骤1:实现通用异常处理包装函数
在公共头文件中定义模板包装函数,统一封装所有异常处理逻辑:
#include <functional> #include <string> template<typename Callable> bool runWithExceptionGuard(Callable&& func, std::string const& scene = "assembler") { try { return std::invoke(std::forward<Callable>(func)); } catch (Exception const& _exception) { serr() << "Exception in " << scene << ": " << boost::diagnostic_information(_exception) << endl; return false; } catch (std::exception const& _e) { serr() << "Unknown exception during " << scene << (_e.what() ? ": " + std::string(_e.what()) : ".") << std::endl; return false; } catch (...) { serr() << "Unknown exception in " << scene << "." << std::endl; return false; } }
步骤2:替换task.cpp中的重复try/catch
所有原有的try/catch块直接替换为包装函数调用,消除所有冗余代码:
// 改造后task.cpp的代码 successful = runWithExceptionGuard([&]() -> bool { if (!stack.parseAndAnalyze(src.first, src.second)) return false; stack.optimize(); return true; }, "assembler");
不同场景下调用时只需修改第二个scene参数即可自定义提示前缀。
内容的提问来源于stack exchange,提问作者Sam
相关产品推荐
相关产品推荐

