2009-03-05 55 views
9

我最近不得不为一位同事开发的现有服务开发一个额外的模块。他放在try/catch块中的主要工作职能用来捕获冒泡到这个级别的所有unhadled例外,带有堆栈跟踪信息等一起记录他们:如何实现顶级异常处理?

try 
{ 
    // do main work 
} 
catch(Exception ex) 
{ 
    // log exception info 
} 

尽管这使得程序非常稳定(如在'不太可能崩溃'),我讨厌它,因为当我测试我的代码时,我没有看到由它造成的异常。当然,我可以查看异常日志并查看是否有新条目,但是我非常希望在抛出异常时获得直接反馈(请将代码中的光标放在代码的右侧)。

至少在我还在编码和测试的时候,我删除了这个顶级的try/catch。但是现在我的任务已经完成了,我必须决定是否将它放回发布版本,否则。 我认为我应该这样做,因为它使服务更稳定,而且它的全部要点是它在后台运行而不需要任何监督。另一方面,我已经读过,应该只是调用特定的例外(如IoException),而不是一般的Exception

你对这个问题的建议是什么?

顺便说一下,该项目是用C#编写的,但我也对非.NET语言的答案感兴趣。

+0

另请参见 http://stackoverflow.com/questions/576532/is-dying-is-awesome-preferred – Brian 2009-03-05 21:51:38

回答

10

放回去。

这个异常应该只在测试时才有意义。否则,将它弹出给用户是没有意义的。

伐木很好。

您还可以使用Visual Studio定义的DEBUG符号作为调试版本的标志。

... 
    } catch(Exception e) { 
#if DEBUG 
      throw; 
#else 
      log as usual 
#endif 
    } 

因此,下一次需要修改调试标志应设置为true,并会出现异常。

+0

嗯,我喜欢调试标志! – Treb 2009-03-05 22:02:25

+0

他不应该用'扔'而不是'扔e'?否则,堆栈跟踪将被清除(或者不太确定)。 – strager 2009-03-05 22:10:14

+0

@strager:是!上面的例子将掩盖原始异常。只需使用'扔'。 – 2009-03-05 22:21:03

2

理想情况下,您希望尽可能接近它发生的位置处理异常,但这并不意味着全局异常处理程序是一个坏主意。特别是对于必须不惜一切代价继续运行的服务。我会继续你一直在做的事情。在调试时禁用它,但将其留在原位进行生产。

请记住它应该用作安全网。尽管如此,他们仍然试图捕捉所有的异常情况,然后才能提升这一点

4

在任何Java应用程序,你几乎总是要定义未捕获的异常的异常处理程序像这样的东西:

Thread.setDefaultUncaughtExceptionHandler(...); 

其中,将捕获这些未捕获的异常对象将至少登录失败等等你有机会了解它。否则,不能保证你会被通知一个线程取得了一个例外 - 除非它是你的主线程。

除了这样做以外,我的大部分线程都有一个try/catch,我会在其中捕获RunnableException(但不是Error)并记录下来......有些线程会在这种情况发生时死亡,其他线程会记录并忽略,其他人将向用户显示投诉,并根据应用程序的需要由用户决定。这个try/catch是线程的根本,Runnable.run()方法或同等方法。由于try/catch位于Thread的根部,因此不需要禁用此捕获。

当我在C#中编写代码时,我的代码类似。但这一切都取决于应用程序的需要。异常是否会破坏数据?那么,不要忽视它。总是记录它,但然后让应用程序死亡。然而,大多数例外都不是这种类型。

2

追求所有例外并使程序“稳定”的愿望非常强烈,这个想法对每个人来说都是非常诱人的。你指出的问题是,这只是一个诡计,并且该程序可能非常糟糕,并且更糟糕,没有失败的迹象。没有人经常监视日志。
我的建议是尝试说服其他开发人员进行广泛的测试,然后将其部署到生产环境而不是外部捕获。

1

如果您想在异常发生时看到异常,可以在Visual Studio中进入DEBUG菜单,选择EXCEPTIONS,并在抛出异常时立即告诉调试器中断。你甚至可以选择什么类型的例外。 :)