捕获异常是不允许的。Checkstyle报告。

5

我正在生成一个嵌入在Maven网站中的Checkstyle报告,其中有一个问题指出不允许捕获异常。我该如何解决这个问题?我不想简单地删除代码,如果我不删除,还有哪些其他的替代方案来解决这个问题。

public void contextInitialized(ServletContextEvent event) {
    super.contextInitialized(event);

    ServletContext context = event.getServletContext();
    setupContext(context);
    LoggingHandler logging = (LoggingHandler) AppContext.getBean( "loggingHandler" );

    try {
        loadClientUserData( context, logging );
        loadMBeans( context, logging );

    } catch (Exception e) {
        throw new RuntimeException( "Error during startup of service !!!" );
    }
}

我仍在学习 Java,因此希望能得到任何形式的指导。

谢谢


1
基本上意味着你应该捕获更具体的异常,而不是捕获通用的 Exception,它会捕获所有继承自它的异常。 - Abubakkar
1
不要忽略你捕获的异常——它告诉你(和其他开发人员)出了什么问题以及在哪里!如果你要抛出另一个异常,将捕获的异常作为[cause](http://docs.oracle.com/javase/8/docs/api/java/lang/Throwable.html#getCause--)包含在内:`throw new RuntimeException("Error during startup of service", e);` - VGR
其他语言如Scala、C#和Kotlin都摒弃了检查异常,因为新手(或刚从大学毕业的人)通常不知道该怎么做,也不应该知道。只有当你知道你想要恢复(这是极其罕见的情况)时,才会添加代码。通常,你希望让客户端失败并继续抛出异常。在这种情况下,捕获任何异常,我通常会使用throw SneakyThrow.sneak(e),它可以在99%的catch块中完成所需的工作。另外1%的情况是用于批处理、故障开放和其他高级用例。 - Dean Hiller
此外,故障开放式设计是危险的(以及在恢复期间进行批处理),因为您的标准API指标无法覆盖它,所以您需要在那里做额外的工作。我曾在Twitter时在这里撰写了一篇关于其中一些内容的文章-> https://blog.twitter.com/engineering/en_us/topics/insights/2019/gotta-catch--em-all - Dean Hiller
3个回答

8
它警告你的是捕获异常是一个糟糕的想法。Exception是你可以捕获的最一般类型的异常。你基本上在说“无论什么问题,我都能处理它”。这不是真的。可能会发生任何奇怪和美妙的问题:键盘中断、磁盘空间满等等。你说loadClientUserData抛出一个ManagerException,所以你应该捕获那个具体的异常,并将其他异常留给更高层次的处理:
try {
     loadClientUserData( context, logging );
     loadMBeans( context, logging );
} catch (ManagerException e) {
     throw new RuntimeException( "Error during startup of service !!!" );
}

更多信息,请参见以下问题:


1
Michael,你真棒。我在帖子中也提到了同样的事情。loadClientUserData会抛出ManagerException异常,那么如果我捕获它,这种情况就可以处理了吗? - user8207635
没错,我会找到一个链接,提供更多有关捕获“异常”的信息。 - Michael
我完全同意你的答案,我们绝不能捕获通用异常,特别是它还捕获RuntimeException。 然而,我发现有几种情况下没有选择:例如,一个框架抛出Exception而不是特定的异常。 例如:https://camel.apache.org/maven/current/camel-core/apidocs/org/apache/camel/CamelContext.html#resolvePropertyPlaceholders(java.lang.String) 在这种情况下,您必须捕获resolvePropertyPlaceholders抛出的异常,并重新抛出包含原始异常的RuntimeException,以防止在方法签名中出现“throws Exception”。 - рüффп
@ рüффп 这在想要在另一个线程中处理异常时非常有用。 - Line

2

你捕获了一个通用异常,但没有对其进行任何处理,这似乎是Checkstyle的问题。你可以重新抛出异常、更好地处理它或通过创建抑制文件来忽略Checkstyle验证。


如果我捕获ManagerException而不是通用异常,那么loadClientUserData()方法抛出的异常会被处理吗? - user8207635
@David 是的,我相信是这样的。 - Michael
是的,我相信如果你这样做,它应该会让你独自一人。 - Arpit

0
你应该捕获最窄的 Exception 子类,原因在这里解释起来太冗长了,简单来说 Exception 包括未经检查的异常。
如果你的方法声明为 throws Exception,那也是一个风格问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接