onSuccess

Evaluates its parameter of type Future[T], and once the Future has been completed successfully, extracts its result as a value of type T and passes it to the inner route.

Signature

def onSuccess(future:  Future[T])(ec: ExecutionContext): Directive1[T]
def onSuccess(future:  Future[L <: HList])(ec: ExecutionContext): Directive[L]

The signature shown is simplified, the real signature uses magnets. [1]

[1]See The Magnet Pattern for an explanation of magnet-based overloading.

Description

The execution of the inner route passed to a onSuccess directive is deferred until the given future has completed successfully, exposing the future’s value as a extraction of type T. If the future fails its failure throwable is bubbled up to the nearest ExceptionHandler.

It is necessary to bring a ExecutionContext into implicit scope for this directive to work.

To handle the Failure case manually as well, use onComplete, instead.

Example

val route =
  path("success") {
    onSuccess(Future { "Ok" }) { extraction =>
      complete(extraction)
    }
  } ~
  path("failure") {
    onSuccess(Future.failed[String](TestException)) { extraction =>
      complete(extraction)
    }
  }


Get("/success") ~> route ~> check {
  responseAs[String] === "Ok"
}

Get("/failure") ~> sealRoute(route) ~> check {
  status === InternalServerError
  responseAs[String] === "Unsuccessful future!"
}