捕获Exception对象是否安全? [英] Is it safe to catch an Exception object
问题描述
我使用依赖异常的Java库。下面的简化代码:
I use a Java lib that relies on exceptions. Simplified code below:
try {
val eventTime = eventTimeString.as[Date]
} catch {
case e: Exception =>
logger.error(s"Can't parse eventTime from $eventTimeString", e)
// take action for the bad Date string.
}
在Java中,我只能捕获将字符串解析为Date的异常,让其余的都保持原状,因为它们可能是致命的。在这里我的理解是,捕获 Exception
意味着捕获任何非致命/非严重的异常。由于它不是相同的捕获 Throwable
,所以很安全-但这真的吗?使用此方法的理由是,未知异常可能从更深的堆栈中抛出,如果它们不是致命的,为什么不捕获所有异常。这在Java中一直是一个问题,在Java中很容易从您进行的直接调用中找到可能的异常,而从更深层的调用中很难找到。
In Java I would catch only the exception from parsing a string into a Date, letting the rest go uncaught since they could be fatal. Here my understanding is that catching Exception
means to catch ANY non-fatal/non-serious exceptions. Since it is not the same a catching Throwable
it is safe—but is it truly? The rationale for using this is that unknown exceptions might be thrown from deeper in the stack and if they are not fatal, why not catch all of them. This has always been a problem in Java where it is easy to find possible exceptions from the direct call you are making but not from deeper. Is this the Scala solution that basically means, 'catch all recoverable exceptions"?
我的问题是;以上代码是否被认为是良好的Scala风格,是否安全?
My question is; is the above code considered good Scala style, is it "safe", meaning better than catching only the string to Date cast exception.
推荐答案
解决问题的样式方面,尝试
,如@LuisMiguelMejiaSuarez所建议的那样,提供了更惯用的Scala样式,例如
Addressing the style aspect of the question, Try
, as suggested by @LuisMiguelMejiaSuarez, provides a more idiomatic Scala style like so
Try(eventTimeString.as[Date]) match {
case Success(eventTimeDate) => // work with eventTimeDate
case Failure(e: IllegalArgumentException) => // work with e
case Failure(e: NullPointerException) => // work with e
...
case Failure(e) => // work with e
}
从语法上看并没有太大区别,但是从概念上讲这是一个很大的转变,因为成功
和 Failure
表示常规的值,而不是某些值特殊的控制结构。 成功
的值类似于 7
的值,而尝试捕获$ c $的值c>更像是
while
或 if-else
控制工具。
Syntactically it appears not much different, however conceptually it is quite a shift because Success
and Failure
represent regular values as opposed to some exceptional control-structure. Success
is a value like 7
is value, whilst try-catch
is more like while
or if-else
control facility.
包装任何可能引发 Try
的库调用(例如由Java库提供的),我们可以利用收益糖来像这样链接调用
Wrapping any library call that might throw in Try
, provided by, say, Java libraries, we could make use of for-yield sugar to chain calls like so
for {
a <- Try(foo)
b <- Try(bar)
c <- Try(qux)
} yield {
// work with a, b and c
}
其中
def foo: Int = {
throw new TimeoutException("foo")
42
}
def bar: String = {
throw new IllegalArgumentException("bar")
"hello"
}
def qux: Boolean = {
throw new NullPointerException("qux")
true
}
我们可以按顺序阅读此链条,而不必中断我们的思想流程,并尝试了解某些例外情况控制结构适合该算法。
We can read this chain sequentially without having to interrupt our flow of thought and try to understand how some exceptional control structure fits into the algorithm.
关于问题的安全性,可以说,我们不应该捕获致命异常,例如 LinkageError
,实际上 Try
与以下例外不匹配
Regarding safety aspect of the question, arguably, we should not catch fatal exception such as LinkageError
, and indeed Try
does not match the following exceptions
VirtualMachineError
ThreadDeath
InterruptedException
LinkageError
ControlThrowable
object Try {
def apply[T](r: => T): Try[T] =
try Success(r) catch {
case NonFatal(e) => Failure(e)
}
}
其中 NonFatal
是
object NonFatal {
def apply(t: Throwable): Boolean = t match {
case _: VirtualMachineError | _: ThreadDeath | _: InterruptedException | _: LinkageError | _: ControlThrowable => false
case _ => true
}
def unapply(t: Throwable): Option[Throwable] = if (apply(t)) Some(t) else None
}
这篇关于捕获Exception对象是否安全?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!