!htp Refactor ExceptionHandler infrastructure for symmetry with RejectionHandler
This commit is contained in:
parent
9c3124f344
commit
7510ec80a4
3 changed files with 19 additions and 14 deletions
|
|
@ -126,11 +126,7 @@ trait RouteTest extends RequestBuilding with RouteTestResultComponent with Marsh
|
|||
securedConnection = defaultHostInfo.securedConnection,
|
||||
defaultHostHeader = defaultHostInfo.host)
|
||||
val ctx = new RequestContextImpl(effectiveRequest, setup.routingLog.requestLog(effectiveRequest), setup.settings)
|
||||
val sealedExceptionHandler = {
|
||||
import setup._
|
||||
if (exceptionHandler.isDefault) exceptionHandler
|
||||
else exceptionHandler orElse ExceptionHandler.default(settings)(setup.executionContext)
|
||||
}
|
||||
val sealedExceptionHandler = setup.exceptionHandler.seal(setup.settings)(setup.executionContext)
|
||||
val semiSealedRoute = // sealed for exceptions but not for rejections
|
||||
Directives.handleExceptions(sealedExceptionHandler) { route }
|
||||
val deferrableRouteResult = semiSealedRoute(ctx)
|
||||
|
|
|
|||
|
|
@ -10,23 +10,35 @@ import akka.http.model._
|
|||
import StatusCodes._
|
||||
|
||||
trait ExceptionHandler extends ExceptionHandler.PF {
|
||||
def isDefault: Boolean
|
||||
|
||||
/**
|
||||
* Creates a new [[ExceptionHandler]] which uses the given one as fallback for this one.
|
||||
*/
|
||||
def withFallback(that: ExceptionHandler): ExceptionHandler
|
||||
|
||||
/**
|
||||
* "Seals" this handler by attaching a default handler as fallback if necessary.
|
||||
*/
|
||||
def seal(settings: RoutingSettings)(implicit ec: ExecutionContext): ExceptionHandler
|
||||
}
|
||||
|
||||
object ExceptionHandler {
|
||||
type PF = PartialFunction[Throwable, Route]
|
||||
|
||||
implicit def apply(pf: PF): ExceptionHandler = apply(default = false)(pf)
|
||||
implicit def apply(pf: PF): ExceptionHandler = apply(knownToBeSealed = false)(pf)
|
||||
|
||||
private def apply(default: Boolean)(pf: PF): ExceptionHandler =
|
||||
private def apply(knownToBeSealed: Boolean)(pf: PF): ExceptionHandler =
|
||||
new ExceptionHandler {
|
||||
def isDefault: Boolean = default
|
||||
def isDefinedAt(error: Throwable) = pf.isDefinedAt(error)
|
||||
def apply(error: Throwable) = pf(error)
|
||||
def withFallback(that: ExceptionHandler): ExceptionHandler =
|
||||
if (!knownToBeSealed) ExceptionHandler(knownToBeSealed = false)(this orElse that) else this
|
||||
def seal(settings: RoutingSettings)(implicit ec: ExecutionContext): ExceptionHandler =
|
||||
if (!knownToBeSealed) ExceptionHandler(knownToBeSealed = true)(this orElse default(settings)) else this
|
||||
}
|
||||
|
||||
def default(settings: RoutingSettings)(implicit ec: ExecutionContext): ExceptionHandler =
|
||||
apply(default = true) {
|
||||
apply(knownToBeSealed = true) {
|
||||
case IllegalRequestException(info, status) ⇒ ctx ⇒ {
|
||||
ctx.log.warning("Illegal request {}\n\t{}\n\tCompleting with '{}' response",
|
||||
ctx.request, info.formatPretty, status)
|
||||
|
|
|
|||
|
|
@ -22,10 +22,7 @@ object Route {
|
|||
def seal(route: Route)(implicit setup: RoutingSetup): Route = {
|
||||
import directives.ExecutionDirectives._
|
||||
import setup._
|
||||
val sealedExceptionHandler =
|
||||
if (exceptionHandler.isDefault) exceptionHandler
|
||||
else exceptionHandler orElse ExceptionHandler.default(settings)
|
||||
handleExceptions(sealedExceptionHandler) {
|
||||
handleExceptions(exceptionHandler.seal(settings)) {
|
||||
handleRejections(rejectionHandler.seal) {
|
||||
route
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue