Skip to content

Commit a70d024

Browse files
SentryMandependabot[bot]rbygrave
authored
Handle Errors before After Handlers (#170)
* Error Handlers handle Throwable It's possible that problems like IllegalAccessError may appear, causing socket hangups if unhandled * remove unneeded generic * Bump the dependencies group with 7 updates Bumps the dependencies group with 7 updates: | Package | From | To | | --- | --- | --- | | io.avaje:avaje-logback-encoder | `0.9` | `0.10` | | io.avaje:avaje-http-api | `2.9-RC7` | `2.9-RC8` | | io.avaje:avaje-htmx-api | `2.9-RC7` | `2.9-RC8` | | [io.avaje:avaje-http-client](https://github.com/avaje/avaje-http-client) | `2.9-RC7` | `2.9-RC8` | | io.avaje:avaje-http-client-generator | `2.9-RC7` | `2.9-RC8` | | io.avaje:avaje-http-jex-generator | `2.9-RC7` | `2.9-RC8` | | [io.github.robaho:httpserver](https://github.com/robaho/httpserver) | `1.0.19` | `1.0.21` | Updates `io.avaje:avaje-logback-encoder` from 0.9 to 0.10 Updates `io.avaje:avaje-http-api` from 2.9-RC7 to 2.9-RC8 Updates `io.avaje:avaje-htmx-api` from 2.9-RC7 to 2.9-RC8 Updates `io.avaje:avaje-http-client` from 2.9-RC7 to 2.9-RC8 - [Release notes](https://github.com/avaje/avaje-http-client/releases) - [Commits](https://github.com/avaje/avaje-http-client/commits) Updates `io.avaje:avaje-http-client-generator` from 2.9-RC7 to 2.9-RC8 Updates `io.avaje:avaje-http-jex-generator` from 2.9-RC7 to 2.9-RC8 Updates `io.avaje:avaje-htmx-api` from 2.9-RC7 to 2.9-RC8 Updates `io.avaje:avaje-http-client` from 2.9-RC7 to 2.9-RC8 - [Release notes](https://github.com/avaje/avaje-http-client/releases) - [Commits](https://github.com/avaje/avaje-http-client/commits) Updates `io.avaje:avaje-http-client-generator` from 2.9-RC7 to 2.9-RC8 Updates `io.avaje:avaje-http-jex-generator` from 2.9-RC7 to 2.9-RC8 Updates `io.github.robaho:httpserver` from 1.0.19 to 1.0.21 - [Commits](robaho/httpserver@1.0.19...1.0.21) --- updated-dependencies: - dependency-name: io.avaje:avaje-logback-encoder dependency-type: direct:production update-type: version-update:semver-minor dependency-group: dependencies - dependency-name: io.avaje:avaje-http-api dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-htmx-api dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-http-client dependency-type: direct:development dependency-group: dependencies - dependency-name: io.avaje:avaje-http-client-generator dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-http-jex-generator dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-htmx-api dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-http-client dependency-type: direct:development dependency-group: dependencies - dependency-name: io.avaje:avaje-http-client-generator dependency-type: direct:production dependency-group: dependencies - dependency-name: io.avaje:avaje-http-jex-generator dependency-type: direct:production dependency-group: dependencies - dependency-name: io.github.robaho:httpserver dependency-type: direct:production update-type: version-update:semver-patch dependency-group: dependencies ... Signed-off-by: dependabot[bot] <support@github.com> * Error Handlers handle Throwable It's possible that problems like IllegalAccessError may appear, causing socket hangups if unhandled * Tidy internals (#169) * tidy internals - rename SPIServiceManager to ServiceManager - move compression to serviceManager - Use Enum `valueof` for HttpMethod mapping * Update Routing.java * handler exceptions before after filters Now Exceptions during handler processing will not skip after handlers - * Update ExceptionHandler.java * iterator * Update ExceptionManager.java * Tidy BaseFilterChain --------- Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Rob Bygrave <robin.bygrave@gmail.com>
1 parent a12b1ca commit a70d024

File tree

5 files changed

+27
-29
lines changed

5 files changed

+27
-29
lines changed

avaje-jex/src/main/java/io/avaje/jex/HttpFilter.java

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

3-
import java.io.IOException;
4-
53
import com.sun.net.httpserver.HttpExchange;
64

75
/**
@@ -37,7 +35,7 @@ public interface HttpFilter {
3735
* @param ctx the {@code Context} of the current request
3836
* @param chain the {@code FilterChain} which allows the next filter to be invoked
3937
*/
40-
void filter(Context ctx, FilterChain chain) throws Exception;
38+
void filter(Context ctx, FilterChain chain);
4139

4240
/**
4341
* Filter chain that contains all subsequent filters that are configured, as well as the final
@@ -51,9 +49,7 @@ interface FilterChain {
5149
* filter in the chain. The {@link HttpFilter} may decide to terminate the chain, by not calling
5250
* this method. In this case, the filter <b>must</b> send the response to the request, because
5351
* the application's {@linkplain HttpExchange exchange} handler will not be invoked.
54-
*
55-
* @throws IOException if an I/O error occurs
5652
*/
57-
void proceed() throws Exception;
53+
void proceed();
5854
}
5955
}
Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,38 @@
11
package io.avaje.jex.core;
22

3-
import java.util.List;
4-
import java.util.ListIterator;
3+
import java.util.Iterator;
54

65
import io.avaje.jex.ExchangeHandler;
76
import io.avaje.jex.HttpFilter;
87
import io.avaje.jex.HttpFilter.FilterChain;
98

109
final class BaseFilterChain implements FilterChain {
1110

12-
private final ListIterator<HttpFilter> iter;
11+
private final Iterator<HttpFilter> filters;
1312
private final ExchangeHandler handler;
1413
private final JdkContext ctx;
14+
private final ServiceManager mgr;
1515

16-
BaseFilterChain(List<HttpFilter> filters, ExchangeHandler handler, JdkContext ctx) {
17-
this.iter = filters.listIterator();
16+
BaseFilterChain(Iterator<HttpFilter> filters, ExchangeHandler handler, JdkContext ctx, ServiceManager mgr) {
17+
this.filters = filters;
1818
this.handler = handler;
1919
this.ctx = ctx;
20+
this.mgr = mgr;
2021
}
2122

2223
@Override
23-
public void proceed() throws Exception {
24-
if (!iter.hasNext()) {
25-
handler.handle(ctx);
26-
ctx.setMode(Mode.AFTER);
24+
public void proceed() {
25+
if (filters.hasNext()) {
26+
filters.next().filter(ctx, this);
2727
} else {
28-
iter.next().filter(ctx, this);
28+
try {
29+
if (!ctx.responseSent()) {
30+
handler.handle(ctx);
31+
}
32+
} catch (Exception t) {
33+
mgr.handleException(ctx, t);
34+
}
2935
}
36+
ctx.setMode(Mode.AFTER);
3037
}
3138
}

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ final class ExceptionManager {
2323
}
2424

2525
@SuppressWarnings("unchecked")
26-
<T extends Exception> ExceptionHandler<Exception> find(Class<T> exceptionType) {
26+
ExceptionHandler<Exception> find(Class<?> exceptionType) {
2727
Class<?> type = exceptionType;
2828
do {
29-
final ExceptionHandler<?> handler = handlers.get(type);
29+
final var handler = handlers.get(type);
3030
if (handler != null) {
3131
return (ExceptionHandler<Exception>) handler;
3232
}
@@ -36,7 +36,7 @@ <T extends Exception> ExceptionHandler<Exception> find(Class<T> exceptionType) {
3636
}
3737

3838
void handle(JdkContext ctx, Exception e) {
39-
final ExceptionHandler<Exception> handler = find(e.getClass());
39+
final var handler = find(e.getClass());
4040
if (handler != null) {
4141
try {
4242
handler.handle(ctx, e);

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

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import com.sun.net.httpserver.HttpHandler;
1010

1111
import io.avaje.jex.HttpFilter;
12-
import io.avaje.jex.compression.CompressionConfig;
1312
import io.avaje.jex.http.NotFoundException;
1413
import io.avaje.jex.routes.SpiRoutes;
1514

@@ -37,7 +36,7 @@ public void handle(HttpExchange exchange) {
3736

3837
if (route == null) {
3938
var ctx = new JdkContext(mgr, exchange, uri, Set.of());
40-
handleException(
39+
mgr.handleException(
4140
ctx,
4241
new NotFoundException(
4342
"No route matching http method %s, with path %s".formatted(routeType.name(), uri)));
@@ -48,10 +47,10 @@ public void handle(HttpExchange exchange) {
4847
JdkContext ctx = new JdkContext(mgr, exchange, route.matchPath(), params, route.roles());
4948
try {
5049
ctx.setMode(Mode.BEFORE);
51-
new BaseFilterChain(filters, route.handler(), ctx).proceed();
50+
new BaseFilterChain(filters.iterator(), route.handler(), ctx, mgr).proceed();
5251
handleNoResponse(exchange);
5352
} catch (Exception e) {
54-
handleException(ctx, e);
53+
mgr.handleException(ctx, e);
5554
}
5655
} finally {
5756
route.dec();
@@ -65,8 +64,4 @@ private void handleNoResponse(HttpExchange exchange) throws IOException {
6564
exchange.sendResponseHeaders(204, -1);
6665
}
6766
}
68-
69-
private void handleException(JdkContext ctx, Exception e) {
70-
mgr.handleException(ctx, e);
71-
}
7267
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ Routing.Type lookupRoutingType(String method) {
115115
}
116116
}
117117

118-
void handleException(JdkContext ctx, Exception e) {
119-
exceptionHandler.handle(ctx, e);
118+
void handleException(JdkContext ctx, Exception t) {
119+
exceptionHandler.handle(ctx, t);
120120
}
121121

122122
void render(Context ctx, String name, Map<String, Object> model) {

0 commit comments

Comments
 (0)