我有一个使用flatMapConcat
合并由解析Json产生的新元素流的源。为此,我使用Alpakka(https://developer.lightbend.com/docs/alpakka/current/data-transformations/json.html)提供的JsonReader。这很好用,但是我想处理向读者展示无效Json的情况。在这种情况下,我希望异常会冒泡给主管,以便它可以重新启动流。
下面是一个简短的片段,展示了坏的json情况:
val systemErrorHandler: Supervision.Decider = {
case e: Exception =>
println("System Error")
Supervision.Restart
case _ => Supervision.Stop
}
val routeErrorHandler: Supervision.Decider = {
case e: Exception =>
println("Route Error")
Supervision.Restart
}
val exceptionStrategy = ActorAttributes.supervisionStrategy(routeErrorHandler)
implicit val actorSystem: ActorSystem = ActorSystem()
implicit val materializer: Materializer = ActorMaterializer(ActorMaterializerSettings(actorSystem).withSupervisionStrategy(systemErrorHandler))
val json = """{"test":"one}"""
val route = Source.single("1").flatMapConcat { _ =>
Source.single(ByteString(json))
.via(JsonReader.select("$")).map(_.utf8String)
}.to(Sink.foreach(println)).withAttributes(exceptionStrategy)
route.run
我希望JsonReader在引发异常时使阶段失败,然后将异常冒泡到routeErrorHandler
。但是,当运行JsonReader阶段失败时,将吞下该异常。我还尝试在流中放置recover
,以将异常抛出到“更高”级别(在子流外部),但是使用routeErrorHandler监控器或放置在ActorMaterializer上的监控器也无法处理该异常。
这是预期的行为吗?如果是这样,确保子流中的异常到达主管策略的正确方法是什么?