recoverRejectionsWith

Signature

def recoverRejectionsWith(f: immutable.Seq[Rejection] 

Description

Low level directive – unless you’re sure you need to be working on this low-level you might instead want to try the handleRejections directive which provides a nicer DSL for building rejection handlers.

Transforms rejections from the inner route with an immutable.Seq[Rejection] => Future[RouteResult] functiona Function<Iterable<Rejection>, CompletionStage<RouteResult>>.

Asynchronous version of recoverRejections.

See recoverRejections (the synchronous equivalent of this directive) for a detailed description.

Note

To learn more about how and why rejections work read the Rejections section of the documentation.

Example

Scala
sourceval authRejectionsToNothingToSeeHere = recoverRejectionsWith { rejections =>
  Future {
    // imagine checking rejections takes a longer time:
    if (rejections.exists(_.isInstanceOf[AuthenticationFailedRejection]))
      Complete(HttpResponse(entity = "Nothing to see here, move along."))
    else
      Rejected(rejections)
  }
}
val neverAuth: Authenticator[String] = creds => None

val route =
  authRejectionsToNothingToSeeHere {
    pathPrefix("auth") {
      path("never") {
        authenticateBasic("my-realm", neverAuth) { user =>
          complete("Welcome to the bat-cave!")
        }
      }
    }
  }

// tests:
Get("/auth/never") ~> route ~> check {
  status shouldEqual StatusCodes.OK
  responseAs[String] shouldEqual "Nothing to see here, move along."
}
Java
sourceimport org.apache.pekko.http.javadsl.server.directives.SecurityDirectives.ProvidedCredentials;

import static org.apache.pekko.http.javadsl.server.Directives.authenticateBasic;
import static org.apache.pekko.http.javadsl.server.Directives.recoverRejectionsWith;

final Function<Optional<ProvidedCredentials>, Optional<Object>> neverAuth =
    creds -> Optional.empty();

final Route originalRoute =
    pathPrefix(
        "auth",
        () ->
            path(
                "never",
                () ->
                    authenticateBasic(
                        "my-realm", neverAuth, obj -> complete("Welcome to the bat-cave!"))));

final Function<Iterable<Rejection>, Boolean> existsAuthenticationFailedRejection =
    rejections ->
        StreamSupport.stream(rejections.spliterator(), false)
            .anyMatch(r -> r instanceof AuthenticationFailedRejection);

final Route route =
    recoverRejectionsWith(
        rejections ->
            CompletableFuture.supplyAsync(
                () -> {
                  if (existsAuthenticationFailedRejection.apply(rejections)) {
                    return RouteResults.complete(
                        HttpResponse.create().withEntity("Nothing to see here, move along."));
                  } else {
                    return RouteResults.rejected(rejections);
                  }
                }),
        () -> originalRoute);

// tests:
testRoute(route)
    .run(HttpRequest.GET("/auth/never"))
    .assertStatusCode(StatusCodes.OK)
    .assertEntity("Nothing to see here, move along.");