completeOrRecoverWith

Signature

def completeOrRecoverWith(magnet: CompleteOrRecoverWithMagnet): Directive1[Throwable] 

Description

If the Future[T] succeeds the request is completed using the value’s marshaller (this directive therefore requires a marshaller for the future’s parameter type to be implicitly available). The execution of the inner route passed to this directive is only executed if the given future completed with a failure, exposing the reason of failure as an extraction of type Throwable.

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

Example

Scala
Java
sourceval route =
  concat(
    path("success") {
      completeOrRecoverWith(Future { "Ok" }) { extraction =>
        failWith(extraction) // not executed.
      }
    },
    path("failure") {
      completeOrRecoverWith(Future.failed[String](TestException)) { extraction =>
        failWith(extraction)
      }
    })

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

Get("/failure") ~> Route.seal(route) ~> check {
  status shouldEqual InternalServerError
  responseAs[String] shouldEqual "Unsuccessful future!"
}
sourceimport static org.apache.pekko.http.javadsl.server.Directives.completeOrRecoverWith;
import static org.apache.pekko.http.javadsl.server.Directives.failWith;

final Route route =
    path(
            "success",
            () ->
                completeOrRecoverWith(
                    () -> CompletableFuture.supplyAsync(() -> "Ok"),
                    Marshaller.stringToEntity(),
                    extraction -> failWith(extraction) // not executed
                    ))
        .orElse(
            path(
                "failure",
                () ->
                    completeOrRecoverWith(
                        () ->
                            CompletableFuture.supplyAsync(
                                () -> {
                                  throw new RuntimeException();
                                }),
                        Marshaller.stringToEntity(),
                        extraction -> failWith(extraction))));

testRoute(route).run(HttpRequest.GET("/success")).assertEntity("Ok");

testRoute(route)
    .run(HttpRequest.GET("/failure"))
    .assertStatusCode(StatusCodes.InternalServerError())
    .assertEntity("There was an internal server error.");