当然,应该在您认为适当的适当级别处理异常。假设您不知道如何处理已检查的异常,并将其包装在适当的自定义未经检查的异常中,只是为了传播到顶层(假设您不处理该包装的异常以及某些介质上的其他可能未经检查的异常)升级原始异常发生的水平(因为你不想或不知道如何))。更进一步,所有未处理的异常(未经检查和检查,未经检查包装)达到顶级(主要方法,webapp控制器等);当然我应该做些什么。我想要做的就是通过使用日志条目通知开发人员出现问题,并告知用户他的请求无法正确处理(根据适用于该异常的消息使用不同的消息)。为此,我在catch块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 :(得分:0)
我认为在你的情况下,这是正确的方法。
通过查看后端服务器名称,数据库凭据,数据库架构等,您不希望用户最好通过查看堆栈跟踪而感到困惑,最坏的情况是泄露可能的安全问题。
您的捕获应该隐藏用户的这些信息并向用户输出有用的错误消息,因此至少他们知道问题所在。
我对您的代码唯一关注的可能是您应该RuntimeException
与Exception
分开(或者Throwable
)
try {
// body of translated JSP here...
}catch(RuntimeException re){
//something unexpected
//handle here
} catch (Exception e) {
//checked exception
//handle here
}
答案 1 :(得分:-1)
使用Exception
包裹您的所有RuntimeException
,并使用main
方法处理它们,或者您定义为最高级别的地方,这是一种非常糟糕的做法。 Exception
的实例应该尽可能地从它们被抛出的位置处理,因为它们存在以识别可以从中恢复的错误。例如,如果您尝试打开文件并获得FileNotFoundException
,则应对此进行操作(显示错误消息,在错误日志中添加条目等)。
大多数情况下,RuntimeException
代表编程错误()。通常情况下,它们表明应用程序处于不稳定状态,即使不是不可能,恢复也很困难。 IllegalStateException
,NullPointerException
和IndexOutOfBoundsException
就是这种情况的例子。
现在,您提出的概念,其中所有RuntimeException
都被顶层方法捕获,对于包含超过几百行代码的任何软件来说都不是一个可行的解决方案,这是一个非常糟糕的做法在较短的课程中。
假设您有一个包含100k行代码的应用程序。抛出异常后,您的顶级方法无法正确处理异常。如果是NullPointerException
该怎么办?它从哪里抛出?那CloneNotSupportedException
怎么样?您最终将拥有一个长达数十页的顶级方法来处理每个可能的异常,并且有史以来最大的if-then-else
语句。
此外,如果您实现了这样的概念,您应该知道,无论何时抛出异常,您的应用程序都将进入顶级方法中的catch
块。一旦记录了错误,您将永远无法将控件返回到生成错误的应用程序部分,因为您将没有引发Exception
的上下文。