为日志记录目的捕获RuntimeException是不好的做法吗?

Wec*_* E. 6 java exception-handling runtimeexception

我发现捕获RuntimeException通常被认为是不好的做法,因为它们无法纠正,通常是程序员错误.

但是,我们有一个(疯狂的)大型应用程序,其中任何部分的更改都可能产生无法预料的后果(是的,这本身就是一个问题).

现在,我们开始在应用程序的顶层开始捕获和记录RuntimeExceptions,这样我们就可以更有效地修复出现这样的流失问题.

像每个优秀的Java团队一样,我们有一个可爱的热心鲍勃非常追随者,绝对禁止我们这样做.

这样做有多糟糕?真的没有这种情况可以接受甚至推荐吗?

Two*_*The 9

捕获RuntimeExceptions不是问题,它们是异常,因此可以捕获并正确处理它们.如果Java开发人员希望您不捕获RuntimeExceptions,他们会将其命名为RuntimeError.

糟糕的是捕获RuntimeExceptions,静默丢弃它们并继续运行,好像什么都没发生过一样.RuntimeExceptions用于通知开发人员/用户关键问题以及程序明显离开预期状态的情况.至少应该记录下来,你应该尝试让程序恢复到舒适的状态.

如果你能在这样的重大失败后继续完全取决于你的申请.Web服务器iE通常会捕获所有异常和错误,只需重新启动相应的Servlet即可继续为请求提供服务.


Max*_*rev 8

抓住它并不总是坏事RuntimeException.但即使你的团队决定不赶上RuntimeException,你也可以随时抓住它,记录一些东西然后重新扔掉它.它根本不会改变你的应用程序逻辑.

现在几乎所有的记录器库都有可能记录有关异常的不同细节(如堆栈跟踪和所有嵌套异常)以及日志消息.

public void doStuff(String param){
  try {
    process(param);
  } catch(RuntimeException e) {
    logger.error("Something weird happened while processing " + param, e);
    throw e;
  }
}
Run Code Online (Sandbox Code Playgroud)


以下是关于上下文的更新,感谢Ralf Kleberhoff指出这一点

最好只在应用程序的顶层记录有关RuntimeException(或任何其他Exception)的消息,以避免在日志中出现有关同一异常的重复消息.

如果您只想添加一些上下文(如参数值,如Ralf Kleberhoff所提到的)并且它不是应用程序顶级catch(并且您确定,顶级catch实际存在),最好创建一个新的Exception并添加原始Exception作为cause进入新的.

public void doStuff(String param){
  try {
    process(param);
  } catch(RuntimeException e) {
    throw new RuntimeException("Something weird happened while processing " + param, e);
  }
}

private void process(String value){
  throw new IllegalStateException("Not implemented yet!");
}
Run Code Online (Sandbox Code Playgroud)

  • 给+1.通常,我不喜欢捕获,记录和重新抛出异常,因为这往往发生在应用程序的多个级别,将一个异常复制到许多日志条目中,但在您的示例中,它完全有意义,因为您记录了上下文信息(param),在异常本身中不存在. (3认同)