在哪里处理致命的例外

时间:2010-04-11 09:34:11

标签: java exception

我正在考虑一个设计,在Swing应用程序中使用自定义UncaughtExceptionHandler处理所有致命异常。这将包括意外的RuntimeExceptions,但也包括在关键资源不可用或以其他方式失败时引发的自定义异常(例如,找不到设置文件或服务器通信错误)。 UncaughtExceptionHandler将根据特定的自定义异常(以及所有未预料到的异常)执行不同的操作,但在所有情况下,应用程序都会向用户显示错误消息并退出。另一种方法是为所有未预料到的异常保留UncaughtExceptionHandler,但处理接近其原点的所有其他致命场景。

我考虑的设计是否合理,或者我应该使用替代品吗?用于处理致命异常的典型方法是什么?

4 个答案:

答案 0 :(得分:2)

通常,很难找到一个好的异常处理策略。每种方法都有其缺点。特别是,你的在某种意义上是好的(处理失败的集中位置)但是有这个缺陷:

您正在描述的异常处理程序将对每个可能的异常进行特殊处理。随着时间的推移,它将成为您的应用程序的焦点:每次添加新功能时,您还需要向处理程序添加异常处理逻辑。这意味着:

  1. 处理程序是其他部分的高度依赖,impl的变化。某些功能可能会触发处理程序中的相应更改。您需要小心保持这两者同步。
  2. 处理程序的一致性较差(有很多原因需要更改) - 它包含应用程序所有功能的交集。
  3. 另一个问题是错误恢复。抛出异常(并向用户显示一些通知)后,用户希望继续使用该应用程序。这意味着如果您的代码开始修改内部数据结构然后因异常而停止,则在允许用户进行其他交互之前,您需要撤消这些修改(或者至少使数据结构恢复到可行状态)。要实现这一目标,需要重新思考数据的组织方式。一种可能的解决方案是DB事务。另一方面,这种表示比普通的数据结构更复杂,因此您需要根据应用程序的需求进行权衡(它是玩具/原型吗?)

答案 1 :(得分:1)

我在大型Swing应用程序中成功使用了本地处理和集中处理的混合。集中处理程序只处理我认为两个或三个特定类型,以及所有未捕获的异常。已经有一段时间了,所以我不记得所有细节,但我们最终得到了一个集中处理程序,它处理了两到三种特定类型的异常和所有未捕获的异常。

我们尽可能使用本地处理,但也定义了类似于ErrorMessageException的东西,它也可以从不与UI交互的后台线程抛出。此异常在中央处理程序中具有特定处理。我们认为这不是最漂亮的解决方案,但它简单易行且运行良好。

任何未捕获的异常都被视为“一般错误”或类似的东西。工作得很好,当然我们试图发布不会导致任何未处理的异常的代码。但是,这在测试中非常有用。

通过这种方法,集中处理程序易于维护,并且没有意外增长。我们也没有看到紧耦合的任何症状,实际上恰恰相反。

答案 2 :(得分:0)

main方法的逻辑包装在try catch块中会更直截了当; e.g。

public static void main(String[] args) {
    try {
        // everything happens here
        System.exit(0);
    } catch (SpecificException ex) {
        ...
    } catch (AnotherException ex) {
        ...
    } catch (Throwable ex) {
        // deal with anything else.
        ...
    }
    System.exit(1);  // tell the world that we failed.
}

答案 3 :(得分:0)

如果您有多线程应用程序(如大多数Swing应用程序),您可能需要考虑通过某个异步队列将异常发送到中央异常处理线程。