Search code examples
scalaakkafuturethrowable

How to handle future completion without explicit handling of non-Exception Throwables


The pattern I keep using for handling Future completions inside of Akka looks something like this:

val caller = sender()
doSomethingAsync().onComplete {
  case Success(arg) => caller ! SuccessMsg(arg)
  case Failure(e:Exception) => caller ! FailureMsg()
  case Failure(e) => throw e // so as to not catch a non-exception Throwable
}

I know i'd much rather map the future and not use onComplete, but mixing Future and Message passing semantics kind of leads you to a place where you end up at a side-effecting operation.

If i leave the Failure(e) case out, I get a warning that my pattern matching will fail, but it's tedious to have to match for the thing I know i shouldn't be catching. Is there a better way to handle success and appropriate failure?


Solution

  • You can use pipeTo to send a message from a Future to an Actor. You can combine it with Future.recover to handle the Failure case.

    import akka.pattern.pipe
    
    doSomethingAsync()
      .map(SuccessMsg)
      .recover{ case e: Exception => FailureMsg() }
      .pipeTo(caller)