recoverRejections
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] => RouteResult
function. a Function<Iterable<Rejection>, RouteResult>
. A RouteResult
RouteResult
is either a Complete(HttpResponse(...))
Complete
containing the HttpResponse
HttpResponse
or a Rejected(rejections)
. Rejected
containing the rejections.
Note
To learn more about how and why rejections work read the Rejections section of the documentation.
Example
- Scala
-
source
val authRejectionsToNothingToSeeHere = recoverRejections { rejections => if (rejections.exists(_.isInstanceOf[AuthenticationFailedRejection])) Complete(HttpResponse(entity = "Nothing to see here, move along.")) else if (rejections == Nil) // see "Empty Rejections" for more details Complete(HttpResponse(StatusCodes.NotFound, entity = "Literally nothing to see here.")) else Rejected(rejections) } val neverAuth: Authenticator[String] = creds => None val alwaysAuth: Authenticator[String] = creds => Some("id") val route = authRejectionsToNothingToSeeHere { pathPrefix("auth") { concat( path("never") { authenticateBasic("my-realm", neverAuth) { user => complete("Welcome to the bat-cave!") } }, path("always") { authenticateBasic("my-realm", alwaysAuth) { user => complete("Welcome to the secret place!") } } ) } } // tests: Get("/auth/never") ~> route ~> check { status shouldEqual StatusCodes.OK responseAs[String] shouldEqual "Nothing to see here, move along." } Get("/auth/always") ~> route ~> check { status shouldEqual StatusCodes.OK responseAs[String] shouldEqual "Welcome to the secret place!" } Get("/auth/does_not_exist") ~> route ~> check { status shouldEqual StatusCodes.NotFound responseAs[String] shouldEqual "Literally nothing to see here." }
- Java
-
source
import akka.http.javadsl.server.directives.SecurityDirectives.ProvidedCredentials; import static akka.http.javadsl.server.Directives.authenticateBasic; import static akka.http.javadsl.server.Directives.recoverRejections; final Function<Optional<ProvidedCredentials>, Optional<Object>> neverAuth = creds -> Optional.empty(); final Function<Optional<ProvidedCredentials>, Optional<Object>> alwaysAuth = creds -> Optional.of("id"); final Route originalRoute = pathPrefix("auth", () -> Directives.concat( path("never", () -> authenticateBasic("my-realm", neverAuth, obj -> complete("Welcome to the bat-cave!")) ), path("always", () -> authenticateBasic("my-realm", alwaysAuth, obj -> complete("Welcome to the secret place!")) ) ) ); final Function<Iterable<Rejection>, Boolean> existsAuthenticationFailedRejection = rejections -> StreamSupport.stream(rejections.spliterator(), false) .anyMatch(r -> r instanceof AuthenticationFailedRejection); final Route route = recoverRejections(rejections -> { if (existsAuthenticationFailedRejection.apply(rejections)) { return RouteResults.complete( HttpResponse.create().withEntity("Nothing to see here, move along.")); } else if (!rejections.iterator().hasNext()) { // see "Empty Rejections" for more details return RouteResults.complete( HttpResponse.create().withStatus(StatusCodes.NOT_FOUND) .withEntity("Literally nothing to see here.")); } else { return RouteResults.rejected(rejections); } }, () -> originalRoute); // tests: testRoute(route).run(HttpRequest.GET("/auth/never")) .assertStatusCode(StatusCodes.OK) .assertEntity("Nothing to see here, move along."); testRoute(route).run(HttpRequest.GET("/auth/always")) .assertStatusCode(StatusCodes.OK) .assertEntity("Welcome to the secret place!"); testRoute(route).run(HttpRequest.GET("/auth/does_not_exist")) .assertStatusCode(StatusCodes.NOT_FOUND) .assertEntity("Literally nothing to see here.");