最近,我必须为同事开发的现有服务开发一个附加模块。他在主工作函数中放置了一个 try/catch 块,用于捕获所有冒泡到此级别的未处理异常,并将它们与堆栈跟踪信息等记录在一起:

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

虽然这使得程序非常稳定(如“不太可能崩溃”),但我讨厌它,因为当我测试我的代码时,我看不到由它引起的异常。当然,我可以查看异常日志并查看是否有新条目,但我非常喜欢在引发异常时立即获取异常的直接反馈(请将光标放在代码中的右行)。

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

您对这个问题有何建议?

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

有帮助吗?

解决方案

放回去。

该例外应仅在测试时有用。否则它没有意义弹出给用户。

记录很好。

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

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

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

其他提示

在任何Java应用程序中,您总是希望为未捕获的异常定义异常处理程序,如下所示:

Thread.setDefaultUncaughtExceptionHandler( ... );

其中捕获这些未捕获异常的对象将至少记录失败,以便您有机会了解它。否则,我们无法保证您甚至会收到一条线程出现异常的通知 - 除非它是您的主线程。

除了这样做之外,我的大多数线程都有一个try / catch,我将捕获 RunnableException (但不是 Error )并记录下来...当发生这种情况时线程将会死亡,其他线程将记录并忽略,其他线程将向用户显示投诉并让用户决定,具体取决于应用程序的需求。此try / catch位于Thread的根, Runnable.run()方法或等效方法中。由于try / catch位于Thread的根目录下,因此无需有时禁用此catch。

当我用C#编写时,我的编码类似。但这一切都取决于应用程序的需要。是一个会破坏数据的例外吗?那么,不要抓住并忽略它。总是记录它,但然后让应用程序死掉。但是,大多数例外都不属于这种情况。

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

请记住,它应该用作安全网。仍然试图在它们提升到那么远之前捕捉所有异常。

捕获所有异常并使程序“稳定”的冲动非常强烈,而且这个想法对每个人来说都非常有吸引力。正如您所指出的,问题在于这只是一个诡计,程序很可能有错误,甚至更糟,没有失败的迹象。没有人定期监控日志。
我的建议是尝试说服其他开发人员进行广泛的测试,然后将其部署到生产中,而无需外部捕获。

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top