在我们的 Scala、Play、Reactivemongo 中,我们在异常处理方面遇到了一个大问题——当出现错误时,在 Iteratee/Enumeratee 或 Actor 系统中,Play 只是将其吞下,而不会将任何错误记录到输出中。所以我们实际上需要猜测这个错误可能发生在哪里,以及为什么会发生。
我们让 Globals 覆盖,总是打印错误,并指定logger.root=TRACE
,但仍然没有看到输出,我们可以从中分析我们的问题。
如何强制让 Play 打印所有错误
在我们的 Scala、Play、Reactivemongo 中,我们在异常处理方面遇到了一个大问题——当出现错误时,在 Iteratee/Enumeratee 或 Actor 系统中,Play 只是将其吞下,而不会将任何错误记录到输出中。所以我们实际上需要猜测这个错误可能发生在哪里,以及为什么会发生。
我们让 Globals 覆盖,总是打印错误,并指定logger.root=TRACE
,但仍然没有看到输出,我们可以从中分析我们的问题。
如何强制让 Play 打印所有错误
没有找到显式记录所有内容的方法,但是有一种方法可以在本地记录异常。
我这样做了:
def recover[T] = Enumeratee.recover[T] {
case (e, input) => Logger.error("Error happened on:" + input, e)
}
然后在所有可能产生错误的枚举对象上使用它
def transform(from: Enumerator[From]): Enumerator[String] = {
heading >>> (from &> recover[From] ><> mapper) >>> tailing
}
在这里,mapper 抛出异常,并且它们都被记录下来。
我认为您的问题在于 Future 在 scala 中的工作方式,让我们以以下示例为例:
val f :Future[Int]= Future {
throw new NullPointerException("NULL")
1
}
f.map(s1 => {println(s" ==> $s1");s" ==> $s1"})
此代码将引发异常,但不会打印堆栈跟踪,因为期货会处理错误。
如果你想得到发生的错误,你可以打电话:
f.onComplete{
case Success(e) => {}
case Failure(e) => e.printStackTrace()
}
e
是一个 throwable,您可以在处理错误时使用它。
在我使用的解决方案中,通过 Play https://www.playframework.com/documentation/2.4.2/ScalaErrorHandling中的 ErrorHandling 覆盖,基本上创建了记录所有错误的 ErrorHandler,并带有所需的详细信息。