为什么
中有例外import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl.Source
object TestExceptionHandling {
def main(args: Array[String]): Unit = {
implicit val actorSystem = ActorSystem()
implicit val materializer = ActorMaterializer()(defaultActorSystem)
Source(List(1, 2, 3)).map { i =>
if (i == 2) {
throw new RuntimeException("Please, don't swallow me!")
} else {
i
}
}.runForeach { i =>
println(s"Received $i")
}
}
}
默默无视?我可以看到在打印Received 1
后流停止,但没有记录任何内容。请注意,问题通常不是日志记录配置,因为如果我在akka.log-config-on-start = on
文件中设置application.conf
,我会看到很多输出。
答案 0 :(得分:15)
我现在正在使用自定义<script>
google.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Month', 'Movie'],
['1', <?php echo $Total[0]; ?>],
['2', <?php echo $Total[1]; ?>],
['3', <?php echo $Total[2]; ?>],
['4', <?php echo $Total[3]; ?>],
['5', <?php echo $Total[4]; ?>],
['6', <?php echo $Total[5]; ?>],
['7', <?php echo $Total[6]; ?>],
['8', <?php echo $Total[7]; ?>],
['9', <?php echo $Total[8]; ?>],
['10', <?php echo $Total[9]; ?>],
['11', <?php echo $Total[10]; ?>],
['12', <?php echo $Total[11]; ?>],
['13', <?php echo $Total[12]; ?>],
['14', <?php echo $Total[13]; ?>],
['15', <?php echo $Total[14]; ?>],
['16', <?php echo $Total[15]; ?>],
['17', <?php echo $Total[16]; ?>],
['18', <?php echo $Total[17]; ?>],
['19', <?php echo $Total[18]; ?>],
['20', <?php echo $Total[19]; ?>],
['21', <?php echo $Total[20]; ?>],
['22', <?php echo $Total[21]; ?>],
['23', <?php echo $Total[22]; ?>],
['24', <?php echo $Total[23]; ?>],
['25', <?php echo $Total[24]; ?>]
]);
... etc...
</script>
来确保正确记录异常,可以这样设置:
Supervision.Decider
另外,正如Vikor Klang所指出的那样,在上面给出的例子中,异常也可以通过
“抓住”val decider: Supervision.Decider = { e =>
logger.error("Unhandled exception in stream", e)
Supervision.Stop
}
implicit val actorSystem = ActorSystem()
val materializerSettings = ActorMaterializerSettings(actorSystem).withSupervisionStrategy(decider)
implicit val materializer = ActorMaterializer(materializerSettings)(actorSystem)
但请注意,此方法无法帮助您
Source(List(1, 2, 3)).map { i =>
if (i == 2) {
throw new RuntimeException("Please, don't swallow me!")
} else {
i
}
}.runForeach { i =>
println(s"Received $i")
}.onComplete {
case Success(_) =>
println("Done")
case Failure(e) =>
println(s"Failed with $e")
}
因为Source(List(1, 2, 3)).map { i =>
if (i == 2) {
throw new RuntimeException("Please, don't swallow me!")
} else {
i
}
}.to(Sink.foreach { i =>
println(s"Received $i")
}).run()
返回run()
。
答案 1 :(得分:5)
当我开始使用akk-streams时,我有类似的问题。 Supervision.Decider
帮助但并非总是如此。
不幸的是,它并没有捕获ActionPublisher
中引发的异常。我看到它被处理了,ActorPublisher.onError
被调用但它没有到达Supervision.Decider
。它适用于文档中提供的简单Stream。
如果我使用Sink.actorRef
,错误也无法触及演员。
为了实验,我尝试了以下示例
val stream = Source(0 to 5).map(100 / _)
stream.runWith(Sink.actorSubscriber(props))
在这种情况下,Decider捕获了异常,但从未到达actor订阅者。
总的来说,我认为这是一种不一致的行为。我不能使用一种机制来处理Stream中的错误。
我原来的问题:Custom Supervision.Decider doesn't catch exception produced by ActorPublisher