我正在看 scala.util.control.NonFatal
。我找不到源,但我相信它类似于this。
他们将LinkageError
声明为Fatal
...
Tomcat(至少在我使用它的最后几年中)始终在catch Throwable
上返回500,而不是因某些错误而崩溃。其他尽最大努力始终将某些东西返回给客户的系统也是如此。
所以,我的最后一个问题是,您何时会使用NonFatal
而不是尽全力尝试提供一些响应?
例如,现在Futures in Twitter's Future library最终无法解决NoSuchMethodError
,因此我的Future
不再解析为Throwable
失败,而是抛出堆栈(与RuntimeException
不同)。实际上,在开源Finagle堆栈中,NoSuchMethodError
将导致客户端套接字连接在客户端上关闭,而不会将500 http错误返回给客户。然后客户认为“嗯,可能是网络问题...为什么我的插座关闭了”
到目前为止,它只给我带来了问题,我承认有些沮丧,但需要对更多用例开放。多年以来,KISS一直将工作包中的每个Throwable
都视为非致命的,但是NonFatal
暗示着在某些用例中我们应该做些不同的事情。
最佳答案
NonFatal
的source code从API docs链接。
致命错误是指您的系统或JVM最有可能无法正确恢复的错误,因此捕获这些错误不是一个好主意。LinkageError
的子类是:ClassCircularityError
,ClassFormatError
,ExceptionInInitializerError
,IncompatibleClassChangeError
,NoClassDefFoundError
,UnsatisfiedLinkError
,VerifyError
。当您的类路径损坏,存在无效或二进制不兼容的类文件时,所有这些都会发生。可以肯定的是,如果在运行时发生整个系统损坏。
要回答这个问题:您应该“让它崩溃”。当需要全包子句时,请始终使用NonFatal
模式匹配。它还会帮您忙,并正确处理与控制流相关的异常(例如NonLocalReturnControl
)。
请注意,与您链接到的旧源代码不同,StackOverflowError
不再不是致命的,该决定已根据SI-7999在Scala 2.11中进行了修订。