Skip to content

Commit cd2363c

Browse files
authored
Add Json body field to HttpResponseException (#129)
* add json exception * test
1 parent f5f2887 commit cd2363c

File tree

6 files changed

+51
-3
lines changed

6 files changed

+51
-3
lines changed

avaje-jex/src/main/java/io/avaje/jex/core/ExceptionManager.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,11 @@ private void unhandledException(JdkContext ctx, Exception e) {
5757

5858
private void defaultHandling(JdkContext ctx, HttpResponseException exception) {
5959
ctx.status(exception.getStatus());
60+
var jsonResponse = exception.jsonResponse();
6061
if (exception.getStatus() == ErrorCode.REDIRECT.status()) {
6162
ctx.performRedirect();
63+
} else if (jsonResponse != null) {
64+
ctx.json(jsonResponse);
6265
} else if (useJson(ctx)) {
6366
ctx.contentType(APPLICATION_JSON).write(asJsonContent(exception));
6467
} else {
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package io.avaje.jex.http;
22

3-
/** Thrown when unable to find a route/resource */
3+
/** Thrown when request is invalid */
44
public class BadRequestException extends HttpResponseException {
55

66
public BadRequestException(String message) {
77
super(400, message);
88
}
9+
10+
public BadRequestException(Object jsonResponse) {
11+
super(400, jsonResponse);
12+
}
913
}

avaje-jex/src/main/java/io/avaje/jex/http/HttpResponseException.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,38 @@
22

33
/**
44
* Throwing an uncaught {@code HttpResponseException} will interrupt http processing and set the
5-
* status code and response body with the given message
5+
* status code and response body with the given message or json body
66
*/
77
public class HttpResponseException extends RuntimeException {
88

99
private final int status;
10+
private final Object jsonResponse;
1011

12+
/**
13+
* @param status the http status to send
14+
* @param message the exception message that will be sent back in the response
15+
*/
1116
public HttpResponseException(int status, String message) {
1217
super(message);
1318
this.status = status;
19+
this.jsonResponse = null;
20+
}
21+
22+
/**
23+
* @param status the http status to send
24+
* @param jsonResponse the response body that will be sent back as json
25+
*/
26+
public HttpResponseException(int status, Object jsonResponse) {
27+
28+
this.status = status;
29+
this.jsonResponse = jsonResponse;
1430
}
1531

1632
public int getStatus() {
1733
return status;
1834
}
35+
36+
public Object jsonResponse() {
37+
return jsonResponse;
38+
}
1939
}
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package io.avaje.jex.http;
22

3-
/** Thrown when unable to find a route/resource */
3+
/** Thrown when server has an internal error */
44
public class InternalServerErrorException extends HttpResponseException {
55

66
public InternalServerErrorException(String message) {
77
super(500, message);
88
}
9+
10+
public InternalServerErrorException(Object jsonResponse) {
11+
super(500, jsonResponse);
12+
}
913
}

avaje-jex/src/main/java/io/avaje/jex/http/NotFoundException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,8 @@ public class NotFoundException extends HttpResponseException {
66
public NotFoundException(String message) {
77
super(404, message);
88
}
9+
10+
public NotFoundException(Object jsonResponse) {
11+
super(404, jsonResponse);
12+
}
913
}

avaje-jex/src/test/java/io/avaje/jex/core/ExceptionManagerTest.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.avaje.jex.core;
22

33
import io.avaje.jex.Jex;
4+
import io.avaje.jex.http.BadRequestException;
45
import io.avaje.jex.http.ErrorCode;
56
import io.avaje.jex.http.HttpResponseException;
67
import io.avaje.jsonb.JsonException;
@@ -9,6 +10,7 @@
910
import org.junit.jupiter.api.Test;
1011

1112
import java.net.http.HttpResponse;
13+
import java.util.Map;
1214

1315
import static org.assertj.core.api.Assertions.assertThat;
1416

@@ -34,6 +36,9 @@ static TestPair init() {
3436
.put("/nested", ctx -> {
3537
throw new JsonException("hmm");
3638
})
39+
.patch("/patch", ctx -> {
40+
throw new BadRequestException(Map.of("error","bad request"));
41+
})
3742
.error(NullPointerException.class, (ctx, exception) -> ctx.text("npe"))
3843
.error(IllegalStateException.class, (ctx, exception) -> ctx.status(222).text("Handled IllegalStateException|" + exception.getMessage()))
3944
.error(JsonException.class, (ctx, exception) -> {throw new IllegalStateException();}));
@@ -60,6 +65,14 @@ void post() {
6065
assertThat(res.body()).isEqualTo("Handled IllegalStateException|foo");
6166
}
6267

68+
@Test
69+
void patch() {
70+
HttpResponse<String> res = pair.request().path("patch").PATCH().asString();
71+
assertThat(res.statusCode()).isEqualTo(400);
72+
assertThat(res.body()).isEqualTo("{\"error\":\"bad request\"}");
73+
assertThat(res.headers().firstValue("Content-Type").get()).contains("application/json");
74+
}
75+
6376
@Test
6477
void expect_fallback_to_fallback() {
6578
HttpResponse<String> res = pair.request().path("nested").PUT().asString();

0 commit comments

Comments
 (0)