You need to enable JavaScript to run this app. C++ 通用日志器与异常分支错误处理的抽象实现方案(支持至C++20)
优惠活动
大模型
产品
解决方案
定价
更多

C++ 通用日志器与异常分支错误处理的抽象实现方案(支持至C++20)

错误处理逻辑抽象实现方案

完全可以用通用模板包装的方式解决重复代码问题,不需要引入复杂的设计模式,所有实现兼容C++20及更早标准,核心思路是把散落在各个成员函数中的错误分支、try-catch框架代码全部收敛到类内部的通用工具方法中,彻底消除重复。

核心逻辑收敛

你当前的错误处理逻辑本质是固定的两套分支,完全可以抽离成统一流程:

  • 不管是主动校验不通过,还是执行中捕获到异常,只要触发错误,就检查是否持有logger:有则记日志返回失败,无则抛异常
  • 业务函数只需要聚焦核心执行逻辑,不用重复编写分支判断、异常捕获的框架代码

具体改造步骤

1. 新增统一错误出口

在foo的私有成员区写一个通用方法,把所有重复的if(m_logger)判断全部收进来,以后再也不用在业务函数里写这套分支:

void handle_error(std::string_view err_msg) const {
    if (m_logger) {
        m_logger->warn(err_msg);
        return;
    }
    throw std::runtime_error(std::string(err_msg));
}

2. 新增通用操作包装模板

写一个私有的模板方法,统一包裹可能抛异常的业务逻辑,把重复的try-catch代码全部抽离:

template <typename Func>
bool wrap_operation(std::string_view op_failed_msg, Func&& func) {
    try {
        std::forward<Func>(func)();
        return true;
    } catch (const std::exception&) {
        // 所有异常统一走错误出口,不用在业务函数里重复判断logger状态
        handle_error(op_failed_msg);
        return false;
    }
}

3. 改造现有bar函数

原来的bar去掉所有重复的框架代码后,会变得非常简洁:

bool bar(const std::filesystem::path& path) {
    // 主动校验不通过时,直接走统一错误出口
    if (!std::filesystem::exists(path)) {
        handle_error("path does not exist.");
        return false;
    }

    // 可能抛异常的核心逻辑直接交给包装模板处理
    return wrap_operation("operation bar failed.", [&] {
        // 只写核心业务逻辑,不需要自己写try-catch和logger判断
        // Do something here that might throw
    });
}

可选优化

如果要进一步减少重复代码,可以加个校验辅助方法,把主动校验的逻辑也收敛:

bool check(bool condition, std::string_view err_msg) const {
    if (condition) return true;
    handle_error(err_msg);
    return false;
}

此时路径校验代码可以简化为:

if (!check(std::filesystem::exists(path), "path does not exist.")) {
    return false;
}

如果需要在日志里附带异常的具体信息,只需要微调wrap_operation模板,支持自定义错误信息生成规则即可,不需要改动业务函数的写法:

template <typename Func, typename ErrMsgGen>
bool wrap_operation(Func&& func, ErrMsgGen&& err_msg_gen) {
    try {
        std::forward<Func>(func)();
        return true;
    } catch (const std::exception& e) {
        handle_error(std::forward<ErrMsgGen>(err_msg_gen)(e));
        return false;
    }
}

调用时可以灵活自定义日志内容:

return wrap_operation([&]{ /* 核心逻辑 */ },
    [](const std::exception& e) {
        return std::string("operation bar failed: ") + e.what();
    });

方案特点

  • 零侵入:所有工具方法都是类的私有成员,不改动类对外的公开接口,也不需要引入复杂的继承层级
  • 易维护:所有错误处理逻辑只集中在3个私有方法里,后续要调整日志级别、替换抛出的异常类型、增加错误上报埋点等,只需要修改这几处,不用遍历所有业务函数
  • 低错漏:所有走包装模板的逻辑自动应用统一错误规则,不会出现某个业务函数漏写logger判断、漏捕获异常的问题,也能避免原代码中throw e导致的异常对象切片问题
  • 兼容性好:核心逻辑在C14标准下即可运行,优化部分完全兼容C20特性,没有硬依赖高版本标准

内容的提问来源于stack exchange,提问作者Joel Bodenmann

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 02:06:02