Leaf Error Middleware is a piece of middleware for Vapor which allows you to return custom 404 and server error pages.
Note that this middleware is designed to be used for Leaf front-end websites only - it should not be used for providing JSON error responses for an API, for example.
First, add LeafErrorMiddleware as a dependency in your Package.swift
file:
dependencies: [
// ...,
.package(url: "https://github.com/brokenhandsio/leaf-error-middleware.git", from: "4.0.0")
],
targets: [
.target(
name: "App",
dependencies: [
.product(name: "Vapor", package: "vapor"),
...,
.product(name: "LeafErrorMiddleware", package: "leaf-error-middleware")
]
),
// ...
]
To use the LeafErrorMiddleware with the default context passed to templates, register the middleware service in configure.swift
to your Application
's middleware (make sure you import LeafErrorMiddleware
at the top):
app.middleware.use(LeafErrorMiddlewareDefaultGenerator.build())
Make sure it appears before all other middleware to catch errors.
Leaf Error Middleware allows you to pass a closure to LeafErrorMiddleware
to generate a custom context for the error middleware. This is useful if you want to be able to tell if a user is logged in on a 404 page for instance.
Register the middleware as follows:
let leafMiddleware = LeafErrorMiddleware() { status, error, req async throws -> SomeContext in
SomeContext()
}
app.middleware.use(leafMiddleware)
The closure receives three parameters:
HTTPStatus
- the status code of the response returned.Error
- the error caught to be handled.Request
- the request currently being handled. This can be used to log information, make external API calls or check the session.
By default, you need to include two Leaf templates in your application:
404.leaf
serverError.leaf
However, you may elect to provide a dictionary mapping arbitrary error responses (i.e >= 400) to custom template names, like so:
let mappings: [HTTPStatus: String] = [
.notFound: "404",
.unauthorized: "401",
.forbidden: "403"
]
let leafMiddleware = LeafErrorMiddleware(errorMappings: mappings) { status, error, req async throws -> SomeContext in
SomeContext()
}
app.middleware.use(leafMiddleware)
// OR
app.middleware.use(LeafErrorMiddlewareDefaultGenerator.build(errorMappings: mapping))
By default, when Leaf Error Middleware catches a 404 error, it will return the 404.leaf
template. This particular mapping also allows returning a 401.leaf
or 403.leaf
template based on the error. Any other error caught will return the serverError.leaf
template. By providing a mapping, you override the default 404 template and will need to respecify it if you want to use it.
If using the default context, the serverError.leaf
template will be passed up to three parameters in its context:
status
- the status code of the error caughtstatusMessage
- a reason for the status codereason
- the reason for the error, if known. Otherwise this won't be passed in.
The 404.leaf
template and any other custom error templates will get a reason
parameter in the context if one is known.