An error handler in Jooby is represented by the Err.Handler class and allows you to log and render exceptions.
NOTE: All headers are reset while generating the error response.
The default error handler does content negotiation and optionally displays friendly error pages using a naming convention.
{
use(new TemplateEngine()); // Hbs, Ftl, etc...
use(new Json()); // A json renderer
get("/", () -> {
...
throw new IllegalArgumentException();
...
});
}If a request to / has an Accept: text/html header. Then, the default Err handler will
ask to a View.Engine to render the err view.
The default model has these attributes:
- message: exception string
- stacktrace: exception stack-trace as an array of string
- status: status code, like
400 - reason: status code reason, like
BAD REQUEST
Here is a simple public/err.html error page:
<html>
<body>
{{ "{{status" }}}}:{{ "{{reason" }}}}
</body>
</html>The HTTP status code of the response will be set as well.
If a request to / has an Accept: application/json header, the default Err handler will
use a renderer to render the err model.
{
"message": "...",
"stacktrace": [],
"status": 500,
"reason": "..."
}In both cases, the error model is the result of err.toMap() which creates a lightweight version of the exception.
The HTTP status code of the response will be set as well.
If the default view resolution and/or err model isn't enough, you can create your own Err handler:
{
err((req, rsp, err) -> {
log.err("err found: ", err);
// do what ever you want here
rsp.send(...);
});
}The Err handlers are executed in the order they were provided (like routes, parsers and renderers). The first Err handler that send an output wins!
{
err(MyException1.class, (req, rsp, err) -> {
MyException1 cause = (MyException1) err.getCause();
// handle MyException1
});
err(MyException2.class, (req, rsp, err) -> {
MyException2 cause = (MyException2) err.getCause();
// handle MyException2
});
err((req, rsp, err) -> {
// handle any other exception
});
}Or you can catch exception base on their response status code (see next section):
{
err(404, (req, rsp, err) -> {
// handle 404
});
err(503, (req, rsp, err) -> {
// handle 503
});
err((req, rsp, err) -> {
// handle any other exception
});
}The default status code for errors is 500, except for:
| Exception | Status Code |
| ---------------------------------- | ----------- |
| java.lang.IllegalArgumentException | 400 |
| | |
| java.util.NoSuchElementException | 400 |
| | |
| java.io.FileNotFoundException | 404 |
Just throw an Err:
throw new Err(403);or add a new entry in the application.conf file:
err.com.security.Forbidden = 403When you now throw a com.security.Forbidden exception, the status code will be 403.