onComplete
Description
Evaluates its parameter of type Future[T]
CompletionStage<T>
, and once it has been completed, extracts its result as a value of type Try[T]
Try<T>
and passes it to the inner route. A Try<T>
can either be a Success
containing the T
value or a Failure
containing the Throwable
.
To handle the Failure
case automatically and only work with the result value, use onSuccess.
To complete with a successful result automatically and just handle the failure result, use completeOrRecoverWith, instead.
Example
- Scala
-
def divide(a: Int, b: Int): Future[Int] = Future { a / b } val route = path("divide" / IntNumber / IntNumber) { (a, b) => onComplete(divide(a, b)) { case Success(value) => complete(s"The result was $value") case Failure(ex) => complete((InternalServerError, s"An error occurred: ${ex.getMessage}")) } } // tests: Get("/divide/10/2") ~> route ~> check { responseAs[String] shouldEqual "The result was 5" } Get("/divide/10/0") ~> Route.seal(route) ~> check { status shouldEqual InternalServerError responseAs[String] shouldEqual "An error occurred: / by zero" }
- Java
-
// import static scala.compat.java8.JFunction.func; // import static akka.http.javadsl.server.PathMatchers.*; final Route route = path(segment("divide").slash(integerSegment()).slash(integerSegment()), (a, b) -> onComplete( () -> CompletableFuture.supplyAsync(() -> a / b), maybeResult -> maybeResult .map(func(result -> complete("The result was " + result))) .recover(new PFBuilder<Throwable, Route>() .matchAny(ex -> complete(StatusCodes.InternalServerError(), "An error occurred: " + ex.getMessage()) ) .build()) .get() ) ); testRoute(route).run(HttpRequest.GET("/divide/10/2")) .assertEntity("The result was 5"); testRoute(route).run(HttpRequest.GET("/divide/10/0")) .assertStatusCode(StatusCodes.InternalServerError()) .assertEntity("An error occurred: / by zero");
Note
Using the onComplete
directive means that you’ll have to explicitly and manually handle failure cases. Doing this for every route in your app will result in a lot of boilerplate code. Most of the time you want to use the Exception Handling mechanism instead.