2013-10-08 94 views
1

当然,异常应该在您认为合适的适当级别进行处理。假设您不知道如何处理checked异常,并将其包装在适当的自定义未经检查的异常中,以传播到最高级别(假定您不处理该包装的异常以及某些介质中的其他可能的未经检查的异常将原始异常发生的级别(因为你不想或不知道如何)级别分开)。更进一步,所有未处理的异常(未经检查和检查,未经检查包装)达到顶层(主要方法,webapp控制器等);当然我应该做点什么。我想要做的就是通过使用日志条目通知开发人员某些错误,并告知用户他的请求无法正确服务(根据适用于该例外的消息使用不同的消息)。要做到这一点,我使用捕获块RuntimeException(如果它捕获的不是自定义的未经检查的异常,我会向用户发送“发生严重问题”或类似的消息;这种非自定义未经检查的异常的概率将被缓存为大于零,并且你必须进行沟通)。一些文章(first,second)建议不要通过catch块中的超类型捕获子类的实例(或者它只与检查的异常有关?)。如果我在catch块中使用了准确的异常类型,我会错过一些未经检查的异常,并且应用程序会崩溃(当然,在那些执行日志记录和通知用户的catch块中会有重复的代码片断)。举个例子,我可以提供在JSP转换阶段建造和使用超类型赶上那超的子类的实例片断顶层的异常处理

// some code 
try { 
    // body of translated JSP here... 
} catch (Exception e) { 
    out.clear(); 
    pageContext.handlePageException(e); 
} 
// some code 

我的问题:是这个概念是正确的catch块使用RuntimeException在顶层向开发者汇报所有问题并向用户通报所有发生的问题?当然,在这种情况下,异常处理只是通知开发人员和用户发生问题,并且没有恢复策略。也许很难将这个概念称为异常处理。请纠正我,我欣赏关于这个概念的任何想法。

回答

0

结束语所有Exception s的一个RuntimeException,并在main方法处理它们,或其它地方你定义为你的最高水平,是一个非常糟糕的做法。 Exception的实例应该尽可能接近它们被抛出的位置,因为它们存在以识别可以从中恢复的错误。例如,如果您尝试打开文件并获取FileNotFoundException,则应对此采取措施(显示错误消息,在错误日志中添加条目等)。

大部分时间,RuntimeException代表编程错误()。通常情况下,他们表示应用程序处于不稳定状态,如果不是不可能的话,恢复也很困难。IllegalStateException,NullPointerExceptionIndexOutOfBoundsException就是这种情况的例子。

现在,您提出的概念,其中所有RuntimeException都被顶级方法所捕获,对于包含超过几百行代码的任何软件来说都不是一个可行的解决方案,在较短的程序中是一种非常糟糕的做法。

假设您有一个具有10万行代码的应用程序。一旦抛出异常,您的顶级方法将无法正确处理异常。如果它是NullPointerException,它应该怎么做?它从哪里抛出?那么CloneNotSupportedException?您将拥有长达数十页的顶级方法,可处理所有可能的例外情况,并拥有史上最大的if-then-else声明。另外,如果你实现了这样一个概念,你应该知道,无论何时抛出异常,你的应用程序都会在你的顶级方法中的catch块中。一旦记录了错误,您将永远无法将控制权返回给您的应用程序的那部分产生错误的部分,因为您将不会拥有引发Exception的上下文。

+0

感谢您的回答。你建议不要推迟处理检查到的顶级异常(尽快完成(发送消息,创建日志条目等)),我同意。但是我应该如何处理发生意外的未经检查的异常(NullPointerException等)?我同意这些未经检查的异常,因为我的编码和恢复是不可能的;但是如果我没有在顶层捕获这些异常,应用程序将崩溃,这种情况比我发现这些异常并提供消息时更糟糕 – stovfl

+0

You可以实现您自己的[UncaughtExceptionHandler](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.UncaughtExceptionHandler.html),并使其记录异常跟踪,显示错误消息给用户,然后关闭应用程序。 – Laf

+0

感谢您的回答和努力 – stovfl

0

我认为在你的情况下这是正确的路要走。

你不希望用户最好通过看到一个堆栈跟踪,并在最坏的情况可能暴露的安全问题,通过看到后端服务器名,数据库凭据,数据库模式等相混淆

你抓应该隐藏这些来自用户的信息并向用户输出有用的错误信息,所以至少他们知道问题是什么。

我与你的代码唯一担心的是也许你应该分开赶上RuntimeExceptionException(甚至Throwable

try { 
    // body of translated JSP here... 
}catch(RuntimeException re){ 
    //something unexpected 
    //handle here 
} catch (Exception e) { 
    //checked exception 
    //handle here 
} 
+0

非常感谢您的回答。阅读许多文章,声称“你不应该通过catch块中的超类型捕获子类的实例”使我困惑。 – stovfl

+0

通常情况下你不应该这样做,但是在main()或最高级别中,有时避免向用户显示很多信息是适当的。 – dkatzel