Jooby catches application exception using the javadoc:ErrorHandler[] class. The
javadoc:DefaultErrorHandler[] error handler produces simple HTML page or JSON based on the value
of the ACCEPT header and log the exception.
Not Found message: Page not found status code: 404
{
"message": "Page not found",
"status": 404,
"reason": "Not Found"
}
GET /xx 404 Not Found io.jooby.StatusCodeException: Not found at ... at ... at ... at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
The javadoc:exception.StatusCodeException[] works as generic exception that let you specify an status code.
throw new StatusCodeException(StatusCode.FORBIDDEN); throw new StatusCodeException(StatusCode.NOT_FOUND); ...
These exception types have a default status code:
-
IllegalArgumentException: BAD_REQUEST(400) (or sub-classes of it)
-
NoSuchElementException: BAD_REQUEST(400) (or sub-classes of it)
-
FileNotFound: NOT_FOUND(404) (or sub-classes of it)
-
Exception: SERVER_ERROR(500) (or sub-classes of it)
To set a custom status code, an entry should be added it to the error code map:
{
errorCode(MyException.class, StatusCode.XXX);
}You can provide your own error handler using the javadoc:Router[error, io.jooby.ErrorHandler] method:
{
error((ctx, cause, statusCode) -> { (1)
Router router = ctx.getRouter();
router.getLog().error("found `{}` error", statusCode.value(), cause); (2)
ctx.setResponseCode(statusCode);
ctx.send("found `" + statusCode.value() + "` error"); (3)
});
}{
error { ctx, cause, statusCode -> (1)
val router = ctx.router
router.log.error("found `{}` error", statusCode.value(), cause) (2)
ctx.responseCode = statusCode
ctx.send("found `${statusCode.value()}` error") (3)
}
}-
Add a global/catch-all exception handler
-
Log the error to logging system
-
Send an error response to the client
You can use the javadoc:Context[render, java.lang.Object] object which looks for a registered javadoc:MessageEncoder[] or javadoc:TemplateEngine[].
The next example produces a HTML or JSON response based on the value of the Accept header.
import static io.jooby.MediaType.json;
import static io.jooby.MediaType.html;
{
install(new MyTemplateEngineModule()); (1)
install(new MyJsonModule()); (2)
error((ctx, cause, statusCode) -> {
Router router = ctx.getRouter();
router.getLog().error("found `{}` error", statusCode.value(), cause);
if (ctx.accept(json)) { (3)
Map error = ...;
ctx.render(error); (4)
} else {
// fallback to html
Map error = ...;
ctx.render(new ModelAndView("error.template", error)); (5)
}
});
}import io.jooby.MediaType.json
import io.jooby.MediaType.html
{
install(MyTemplateEngineModule()) (1)
install(MyJsonModule()) (2)
error {ctx, cause, statusCode ->
val router = ctx.router
router.log.error("found `{}` error", statusCode.value(), cause)
if (ctx.accept(json)) { (3)
val error = mapOf(...)
ctx.render(error) (4)
} else {
// fallback to html
val error = mapOf(...)
ctx.render(ModelAndView("error.template", error)) (5)
}
}
}-
Install one of the available template engines
-
Install one of the available json modules
-
Test if the accept header matches the
application/jsoncontent type -
Render json if matches
-
Render html as fallback
In addition to the generic/global error handler you can catch specific status code:
import static io.jooby.StatusCode.NOT_FOUND;
{
error(NOT_FOUND, (ctx, cause, statusCode) -> {
ctx.send(statusCode); (1)
});
}import io.jooby.StatusCode.NOT_FOUND
{
error (NOT_FOUND) { ctx, cause, statusCode ->
ctx.send(statusCode) (1)
}
}-
Send
404response to the client
Here we kind of silence all the 404 response due we don’t log anything and send an empty response.
|
Tip
|
The javadoc:Context[send, io.jooby.StatusCode] method send an empty response to the client |
In addition to the generic/global error handler you can catch specific exception type:
{
error(MyException.class, (ctx, cause, statusCode) -> {
// log and process MyException
});
}{
error (MyException::class) { ctx, cause, statusCode ->
// log and process MyException
}
}