When developing applications you should assume that there will be unexpected issues. For this, Akka provides a set of supervision strategies to deal with errors within your actors. Akka streams is no different, in fact its error handling strategies used those actor supervision strategies as inspiration.
There are three ways to handle exceptions in your application code:
Stop
- The stream is completed with failureResume
- The problematic element is dropped and the stream continuesRestart
- The problematic element is dropped and the stream continues after restarting the stage. Restarting the stage means that any accumulated state is cleared.Default supervision strategy for a stream can be defined via the settings of the materializer. And this can be set for the whole stream or just for a particular stage.
implicit val system = ActorSystem()
implicit val ec = system.dispatcher
val decider: Supervision.Decider = {
case _: ArithmeticException =>
println("Dropping element because of an ArithmeticException (i.e. Divide by zero)")
Supervision.Resume
case _ => Supervision.Stop
}
implicit val materializer = ActorMaterializer(
ActorMaterializerSettings(system).withSupervisionStrategy(decider)
)
val source = Source(0 to 5).map(100 / _)
val result = source.runWith(Sink.foreach(println))
.onComplete(_ => system.terminate())
Akka Streams also provides a RestartSource
, RestartSink
, RestartFlow
for implementing the so called exponential backoff supervision strategy - starting a stage again when it fails each time with a growing time delay between restarts.
See more in the Java or Scala documentation.