【问题标题】:How to make exception code DRY?如何使异常代码干燥?
【发布时间】:2014-12-13 08:47:17
【问题描述】:

我正在尝试使用异常捕获重新抛出来调试我的应用程序。我的异常处理代码比我正在调试的一些块要长,而且都是复制粘贴的。

有没有更好的方法来重复表达下面的代码?我怀疑宏是这里的方法,但我通常会避免使用像瘟疫这样的宏。

  try {
   // Code here...
  }
  catch (std::exception & e)
  {
    ErrorMsgLog::Log("Error", "std exception caught in " __func__ " " __FILE__ " " __LINE__, e.what());
    throw e;
  }
  catch (Exception & e)
  {
    ErrorMsgLog::Log("Error", "Builder exception caught in " __func__ " " __FILE__ " " __LINE__, e.Message);
    throw e;
  }
  catch (...)
  {
    ErrorMsgLog::Log("Error", "Unknown exception caught in " __func__ " " __FILE__ " " __LINE__);
    throw std::runtime_error ("Unknown Exception in " __func__ " " __FILE__ " " __LINE__);
  }

【问题讨论】:

  • forward 模板化函数的所有异常?
  • 使Exception 成为std::exception 的子类型,就像任何正常的异常类型一样。
  • 由于您要避免使用宏,我可以建议您将整个应用程序代码封装在这个try catch 块中吗?这样,您只需要使用简单的 try catch(...) 块来封装引发异常的代码块,该块只会执行 throw;,直到它到达主要的 try catch 块。
  • 您是否考虑过在抛出而不是在捕获异常时记录异常?至少你可以让__FILE____LINE__ 有用。顺便说一句,您在记录的消息中撒谎,实际上您并没有抓住它。
  • 您提出的问题有一个非常干净的解决方案。看看stackoverflow.com/questions/847279/… 接受的答案。

标签: c++ exception dry c++03


【解决方案1】:

实现这一点的最佳方法可能是使用宏。宏定义有点难看,但是调用宏会很容易,而且你不需要重新组织你的代码。这是一个示例,展示了如何实现它:

#define RUN_SAFE(code) try {\
    code\
  }\
  catch (std::exception & e)\
  {\
    ErrorMsgLog::Log("Error");\
    throw e;\
  }\
  catch (Exception & e)\
  {\
    ErrorMsgLog::Log("Error");\
    throw e;\
  }\
  catch (...)\
  {\
    ErrorMsgLog::Log("Error");\
    throw std::exception();\
  }\

int main(){
  RUN_SAFE(
    cout << "Hello World\n";
  )
}

如果你真的坚持不使用宏,你可以使用@juanchopanza 建议的方法,并使用高阶函数进行检查,将代码作为参数。不过,这种方法可能需要您稍微重构一下代码。以下是你可以如何实现它:

void helloWorld(){
  cout << "Hello World\n";
}

void runSafe(void (*func)()){
  try {
      func();
    }
    catch (std::exception & e)
    {
      ErrorMsgLog::Log("Error");
      throw e;
    }
    catch (Exception & e)
    {
      ErrorMsgLog::Log("Error");
      throw e;
    }
    catch (...)
    {
      ErrorMsgLog::Log("Error");
      throw std::exception();
    }
}

int main(){
  runSafe(helloWorld);
}

【讨论】:

  • 由于您使用的是 c++,因此请使用 std::function 而不是原始函数指针。对函数参数类型和返回类型使用模板参数。
猜你喜欢
  • 2013-09-16
  • 1970-01-01
  • 1970-01-01
  • 2011-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多