Skip to content

Commit 08ff1c2

Browse files
committed
err handler on specific exception/code fix #382
1 parent 79471c4 commit 08ff1c2

3 files changed

Lines changed: 141 additions & 6 deletions

File tree

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package org.jooby.issues;
2+
3+
import org.jooby.Err;
4+
import org.jooby.test.ServerFeature;
5+
import org.junit.Test;
6+
7+
public class Issue382 extends ServerFeature {
8+
9+
{
10+
11+
get("/err1", () -> {
12+
throw new IllegalArgumentException("err1");
13+
});
14+
15+
get("/err2", () -> {
16+
throw new IllegalStateException("err2");
17+
});
18+
19+
get("/400", () -> {
20+
throw new Err(404);
21+
});
22+
23+
get("/500", () -> {
24+
throw new Err(500);
25+
});
26+
27+
err(IllegalArgumentException.class, (req, rsp, err) -> {
28+
rsp.send(err.getCause().getClass().getSimpleName());
29+
});
30+
31+
err(IllegalStateException.class, (req, rsp, err) -> {
32+
rsp.send(err.getCause().getClass().getSimpleName());
33+
});
34+
35+
err(404, (req, rsp, err) -> {
36+
rsp.send("Not found");
37+
});
38+
39+
err((req, rsp, err) -> {
40+
rsp.send("Fallback");
41+
});
42+
}
43+
44+
@Test
45+
public void shouldHandleSpecificErrTypes() throws Exception {
46+
request()
47+
.get("/err1")
48+
.expect("IllegalArgumentException");
49+
50+
request()
51+
.get("/err2")
52+
.expect("IllegalStateException");
53+
54+
request()
55+
.get("/400")
56+
.expect("Not found");
57+
58+
request()
59+
.get("/500")
60+
.expect("Fallback");
61+
}
62+
63+
}

jooby/src/main/java/org/jooby/Routes.java

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2492,5 +2492,40 @@ Route.Collection complete(String method, String pattern, Route.Complete handler,
24922492
* @param err A route error handler.
24932493
* @return This jooby instance.
24942494
*/
2495-
Routes err(final Err.Handler err);
2495+
Routes err(Err.Handler err);
2496+
2497+
/**
2498+
* Setup a route error handler.The error handler will be executed if the current exception is an
2499+
* instance of this type.
2500+
*
2501+
* @param type Exception type. The error handler will be executed if the current exception is an
2502+
* instance of this type.
2503+
* @param handler A route error handler.
2504+
* @return This jooby instance.
2505+
*/
2506+
default Routes err(final Class<? extends Throwable> type, final Err.Handler handler) {
2507+
return err((req, rsp, err) -> {
2508+
Throwable cause = err.getCause();
2509+
if (type.isInstance(cause)) {
2510+
handler.handle(req, rsp, err);
2511+
}
2512+
});
2513+
}
2514+
2515+
/**
2516+
* Setup a route error handler. The error handler will be executed if current status code matches
2517+
* the one provided.
2518+
*
2519+
* @param statusCode The status code to match.
2520+
* @param handler A route error handler.
2521+
* @return This jooby instance.
2522+
*/
2523+
default Routes err(final int statusCode, final Err.Handler handler) {
2524+
return err((req, rsp, err) -> {
2525+
if (statusCode == err.statusCode()) {
2526+
handler.handle(req, rsp, err);
2527+
}
2528+
});
2529+
}
2530+
24962531
}

md/err.md

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ HTTP status code will be set too.
6363

6464
## custom err handler
6565

66-
If the default view resolution and/or err model isn't enough, you can create your own err handler.
66+
If the default view resolution and/or err model isn't enough, you can create your own err handler:
6767

6868
```java
6969
{
@@ -75,9 +75,48 @@ If the default view resolution and/or err model isn't enough, you can create you
7575
}
7676
```
7777

78-
Err handler are executed in the order they were provided (like routes, parser and renderers).
78+
Err handler are executed in the order they were provided (like routes, parsers and renderers).
7979
The first err handler that send an output wins!
8080

81+
### catch specific exception or status code
82+
83+
84+
```java
85+
{
86+
err(MyException1.class, (req, rsp, err) -> {
87+
MyException1 cause = (MyException1) err.getCause();
88+
// handle MyException1
89+
});
90+
91+
err(MyException2.class, (req, rsp, err) -> {
92+
MyException2 cause = (MyException2) err.getCause();
93+
// handle MyException2
94+
});
95+
96+
err((req, rsp, err) -> {
97+
// handle any other exception
98+
});
99+
}
100+
```
101+
102+
Or you can catch exception base on their response status code (see next section):
103+
104+
```java
105+
{
106+
err(404, (req, rsp, err) -> {
107+
// handle 404
108+
});
109+
110+
err(503, (req, rsp, err) -> {
111+
// handle 503
112+
});
113+
114+
err((req, rsp, err) -> {
115+
// handle any other exception
116+
});
117+
}
118+
```
119+
81120
## status code
82121

83122
Default status code is ```500```, except for:
@@ -106,6 +145,4 @@ or add a new entry in the ```application.conf``` file:
106145
err.com.security.Forbidden = 403
107146
```
108147

109-
```java
110-
throw new Forbidden();
111-
```
148+
So, now if you throw a ```com.security.Forbidden``` exception the status code will be ```403```.

0 commit comments

Comments
 (0)