什么是Scala中的Boxed Error?

41
当我运行我的应用程序时,浏览器会显示什么。
[ExecutionException: Boxed Error]

它没有提到行号等任何内容。

在控制台中,我有以下内容

! @6elaah0c8 - Internal server error, for (GET) [/testlearn] ->

play.api.Application$$anon$1: Execution exception[[ExecutionException: Boxed Error]]
    at play.api.Application$class.handleError(Application.scala:289) ~[play_2.10.jar:2.1.1]
    at play.api.DefaultApplication.handleError(Application.scala:383) [play_2.10.jar:2.1.1]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$17$$anonfun$apply$24.apply(PlayDefaultUpstreamHandler.scala:326) [play_2.10.jar:2.1.1]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$17$$anonfun$apply$24.apply(PlayDefaultUpstreamHandler.scala:324) [play_2.10.jar:2.1.1]
    at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.1]
    at play.api.libs.concurrent.PlayPromise$$anonfun$extend1$1.apply(Promise.scala:113) [play_2.10.jar:2.1.1]
java.util.concurrent.ExecutionException: Boxed Error
    at scala.concurrent.impl.Promise$.resolver(Promise.scala:52) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
    at scala.concurrent.impl.Promise$.scala$concurrent$impl$Promise$$resolveTry(Promise.scala:44) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
    at scala.concurrent.impl.Promise$DefaultPromise.tryComplete(Promise.scala:116) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
    at scala.concurrent.Promise$class.complete(Promise.scala:55) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
    at scala.concurrent.impl.Promise$DefaultPromise.complete(Promise.scala:58) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:23) [factorie-1.0.0-M4-jar-with-dependencies.jar:na]
Caused by: java.lang.AssertionError: assertion failed
    at scala.Predef$.assert(Predef.scala:165) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
    at cc.factorie.util.TraversableExtras$class.max2ByDouble(TraversableExtras.scala:95) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
    at cc.factorie.package$$anon$2.max2ByDouble(package.scala:148) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
    at cc.factorie.optimize.SampleRankExample.accumulateExampleInto(SampleRank.scala:31) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
    at cc.factorie.optimize.OnlineTrainer$$anonfun$processExamples$3.apply(Trainer.scala:72) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
    at cc.factorie.optimize.OnlineTrainer$$anonfun$processExamples$3.apply(Trainer.scala:63) ~[factorie-1.0.0-M4-jar-with-dependencies.jar:na]
2个回答

57
"Boxed Error"是Scala对Future中抛出的Error的响应。在Java中,因此也在Scala中,类型为Error的子类具有特殊含义,表示致命错误。请参见异常和错误之间的区别。简而言之,javadoc说:

错误是Throwable的一个子类,用于指示严重问题,合理的应用程序不应尝试捕获大多数这样的错误是异常条件。

与在future中抛出其他Throwable不同,当抛出Error的子类时,默认的Scala解析器将使用消息字符串“Boxed Error”将Error包装在java.util.concurrent.ExecutionException中,并使您的承诺失败。

引用关于Error被抛出的futures文档 http://docs.scala-lang.org/overviews/core/futures.html

[错误] 异常将在执行失败的异步计算的线程中重新抛出。这样做的理由是防止传播由客户端代码通常不处理的关键和控制流相关异常,同时通知客户端计算失败的未来。

如果您想对Failure进行特殊处理,则可以提取抛出的原始Error(但不太适合模式匹配),方法是使用ExecutionException#getCause()


我有点不明白为什么任何可抛出的异常都会“泄漏”到Future中,首先原始的AssertionError不应该被捕获并传递给future的oncomplete回调函数吗? - lisak
1
我看到Future处理了NonFatal异常,但是AssertionError实际上也是一个NonFatal异常,所以它应该被捕获并作为一个值传递。 - lisak

3

我不知道这是什么“盒式错误”,但根据您的堆栈跟踪,根本问题来自于factorie库中的max2Double方法,在第95行

源代码摘录:

/**Returns both the maximum element and the second-to-max element */
  def max2ByDouble(extractor: A => Double): (A, A) = {
    val s1 = t.toSeq
    assert(s1.length > 1)   // <<<== HERE
    var best1 = Double.NegativeInfinity
    ...

看起来你的Traversable为空。


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