# error handling An error handler in Jooby is represented by the [Err.Handler]({{defdocs}}/Err.Handler.html) class and allows you to log and render exceptions. > NOTE: All headers are reset while generating the error response. ## default err handler The [default error handler]({{defdocs}}/Err.DefHandler.html) does content negotiation and optionally displays friendly error pages using a naming convention. ```java { use(new TemplateEngine()); // Hbs, Ftl, etc... use(new Json()); // A json renderer get("/", () -> { ... throw new IllegalArgumentException(); ... }); } ``` ### html If a request to ```/``` has an ```Accept: text/html``` header. Then, the default Err handler will ask to a [View.Engine]({{defdocs}}/View.Engine.html) 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 {{ "{{status" }}}}:{{ "{{reason" }}}} ``` The HTTP status code of the response will be set as well. ### no html If a request to ```/``` has an ```Accept: application/json``` header, the default Err handler will use a [renderer]({{defdocs}}/Renderer.html) to render the ```err``` model. ```json { "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. ## custom err handler If the default view resolution and/or err model isn't enough, you can create your own Err handler: ```java { 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! ### catch a specific exception or status code ```java { 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): ```java { err(404, (req, rsp, err) -> { // handle 404 }); err(503, (req, rsp, err) -> { // handle 503 }); err((req, rsp, err) -> { // handle any other exception }); } ``` ## status code 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 | ``` ### custom status codes Just throw an [Err]({{defdocs}}/Err.html): ```java throw new Err(403); ``` or add a new entry in the ```application.conf``` file: ```properties err.com.security.Forbidden = 403 ``` When you now throw a ```com.security.Forbidden``` exception, the status code will be ```403```.