Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions vertx-web/src/main/java/io/vertx/ext/web/Router.java
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,18 @@ static Router router(Vertx vertx) {
@Fluent
Router errorHandler(int statusCode, Handler<RoutingContext> errorHandler);

/**
* Specify an handler to handle an error for any status code that doesn't have a specific handler assigned.
* The handler will be called when the context fails and other failure handlers didn't write the reply or when an exception is thrown inside an handler.
* You <b>must not</b> use {@link RoutingContext#next()} inside the error handler
* This does not affect the normal failure routing logic.
*
* @param errorHandler error handler. Note: You <b>must not</b> use {@link RoutingContext#next()} inside the provided handler
* @return a reference to this, so the API can be used fluently
*/
@Fluent
Router uncaughtErrorHandler(Handler<RoutingContext> errorHandler);

/**
* Used to route a context to the router. Used for sub-routers. You wouldn't normally call this method directly.
*
Expand Down
6 changes: 6 additions & 0 deletions vertx-web/src/main/java/io/vertx/ext/web/impl/RouterImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,12 @@ public synchronized Router errorHandler(int statusCode, Handler<RoutingContext>
return this;
}

@Override
public synchronized Router uncaughtErrorHandler(Handler<RoutingContext> errorHandler) {
state = state.setUncaughtErrorHandler(errorHandler);
return this;
}

synchronized void add(RouteImpl route) {
state = state.addRoute(route);
// notify the listeners as the routes are changed
Expand Down
35 changes: 32 additions & 3 deletions vertx-web/src/main/java/io/vertx/ext/web/impl/RouterState.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,15 +57,17 @@ final class RouterState {
private final TreeSet<RouteImpl> routes;
private final int orderSequence;
private final Map<Integer, Handler<RoutingContext>> errorHandlers;
private final Handler<RoutingContext> uncaughtErrorHandler;
private final Handler<Router> modifiedHandler;
private final AllowForwardHeaders allowForward;
private final Map<String, Object> metadata;

public RouterState(RouterImpl router, TreeSet<RouteImpl> routes, int orderSequence, Map<Integer, Handler<RoutingContext>> errorHandlers, Handler<Router> modifiedHandler, AllowForwardHeaders allowForward, Map<String, Object> metadata) {
public RouterState(RouterImpl router, TreeSet<RouteImpl> routes, int orderSequence, Map<Integer, Handler<RoutingContext>> errorHandlers, final Handler<RoutingContext> uncaughtErrorHandler, Handler<Router> modifiedHandler, AllowForwardHeaders allowForward, Map<String, Object> metadata) {
this.router = router;
this.routes = routes;
this.orderSequence = orderSequence;
this.errorHandlers = errorHandlers;
this.uncaughtErrorHandler = uncaughtErrorHandler;
this.modifiedHandler = modifiedHandler;
this.allowForward = allowForward;
this.metadata = metadata;
Expand All @@ -78,6 +80,7 @@ public RouterState(RouterImpl router) {
0,
null,
null,
null,
AllowForwardHeaders.NONE,
null);
}
Expand All @@ -99,6 +102,7 @@ RouterState setRoutes(Set<RouteImpl> routes) {
new TreeSet<>(routeComparator),
this.orderSequence,
this.errorHandlers,
this.uncaughtErrorHandler,
this.modifiedHandler,
this.allowForward,
this.metadata);
Expand All @@ -119,6 +123,7 @@ RouterState addRoute(RouteImpl route) {
routes,
this.orderSequence,
this.errorHandlers,
this.uncaughtErrorHandler,
this.modifiedHandler,
this.allowForward,
this.metadata);
Expand All @@ -130,6 +135,7 @@ RouterState clearRoutes() {
new TreeSet<>(routeComparator),
this.orderSequence,
this.errorHandlers,
null,
this.modifiedHandler,
this.allowForward,
this.metadata);
Expand All @@ -147,6 +153,7 @@ RouterState removeRoute(RouteImpl route) {
routes,
this.orderSequence,
this.errorHandlers,
this.uncaughtErrorHandler,
this.modifiedHandler,
this.allowForward,
this.metadata);
Expand All @@ -162,6 +169,7 @@ RouterState incrementOrderSequence() {
this.routes,
this.orderSequence + 1,
this.errorHandlers,
this.uncaughtErrorHandler,
this.modifiedHandler,
this.allowForward,
this.metadata);
Expand All @@ -173,6 +181,7 @@ RouterState setOrderSequence(int orderSequence) {
this.routes,
orderSequence,
this.errorHandlers,
this.uncaughtErrorHandler,
this.modifiedHandler,
this.allowForward,
this.metadata);
Expand All @@ -188,16 +197,20 @@ RouterState setErrorHandlers(Map<Integer, Handler<RoutingContext>> errorHandlers
this.routes,
this.orderSequence,
errorHandlers,
this.uncaughtErrorHandler,
this.modifiedHandler,
this.allowForward,
this.metadata);
}

Handler<RoutingContext> getErrorHandler(int errorCode) {
if (errorHandlers != null) {
return errorHandlers.get(errorCode);
final Handler<RoutingContext> errorHandler = errorHandlers.get(errorCode);
if (errorHandler != null) {
return errorHandler;
}
}
return null;
return uncaughtErrorHandler;
}

RouterState putErrorHandler(int errorCode, Handler<RoutingContext> errorHandler) {
Expand All @@ -206,6 +219,7 @@ RouterState putErrorHandler(int errorCode, Handler<RoutingContext> errorHandler)
this.routes,
this.orderSequence,
this.errorHandlers == null ? new HashMap<>() : new HashMap<>(errorHandlers),
this.uncaughtErrorHandler,
this.modifiedHandler,
this.allowForward,
this.metadata);
Expand All @@ -214,6 +228,18 @@ RouterState putErrorHandler(int errorCode, Handler<RoutingContext> errorHandler)
return newState;
}

RouterState setUncaughtErrorHandler(Handler<RoutingContext> errorHandler) {
return new RouterState(
this.router,
this.routes,
this.orderSequence,
this.errorHandlers,
errorHandler,
this.modifiedHandler,
this.allowForward,
this.metadata);
}

public Handler<Router> getModifiedHandler() {
return modifiedHandler;
}
Expand All @@ -224,6 +250,7 @@ public RouterState setModifiedHandler(Handler<Router> modifiedHandler) {
this.routes,
this.orderSequence,
this.errorHandlers,
this.uncaughtErrorHandler,
modifiedHandler,
this.allowForward,
this.metadata);
Expand All @@ -235,6 +262,7 @@ public RouterState setAllowForward(AllowForwardHeaders allow) {
this.routes,
this.orderSequence,
this.errorHandlers,
this.uncaughtErrorHandler,
this.modifiedHandler,
allow,
this.metadata);
Expand All @@ -256,6 +284,7 @@ public RouterState putMetadata(String key, Object value) {
this.routes,
this.orderSequence,
this.errorHandlers,
this.uncaughtErrorHandler,
this.modifiedHandler,
this.allowForward,
Collections.unmodifiableMap(metadata));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3693,6 +3693,14 @@ public void testExtractCallee() throws Exception {
200, "OK");
}

@Test
public void testUncaughtErrorHandler() throws Exception {
router.route().consumes("text/html").handler(rc -> rc.response().end());
router.uncaughtErrorHandler(context -> context.response().setStatusCode(context.statusCode()).setStatusMessage("Dumb").end());

testRequestWithContentType(HttpMethod.GET, "/foo", "something/html", 415, "Dumb");
}

@Test
public void testErrorHandlerInvokedOnce() throws Exception {
AtomicInteger errorHandlerInvocations = new AtomicInteger();
Expand Down
Loading