Skip to content

Commit 14a6f54

Browse files
committed
fix #2772 Subrouter failure handler is ignored
1 parent 22f51bc commit 14a6f54

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

vertx-web/src/main/java/io/vertx/ext/web/impl/RoutingContextImplBase.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,19 @@ boolean iterateNext() {
163163
currentRoute.handleFailure(this);
164164
return true;
165165
}
166+
167+
RouterImpl subRouter = (RouterImpl) currentRoute.getSubRouter();
168+
if (subRouter != null) {
169+
int statusCode = statusCode();
170+
if (statusCode == -1) {
171+
statusCode = failed ? 500 : matchFailure;
172+
}
173+
Handler<RoutingContext> errorHandler = subRouter.getErrorHandlerByStatusCode(statusCode);
174+
if (errorHandler != null) {
175+
errorHandler.handle(this);
176+
return true;
177+
}
178+
}
166179
} catch (Throwable t) {
167180
handleInHandlerRuntimeFailure(currentRoute.getRouter(), failed, t);
168181
return true;

vertx-web/src/test/java/io/vertx/ext/web/tests/SubRouterTest.java

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818

1919
import io.vertx.core.Handler;
2020
import io.vertx.core.Vertx;
21+
import io.vertx.core.http.HttpClientResponse;
2122
import io.vertx.core.http.HttpMethod;
2223
import io.vertx.ext.web.Router;
2324
import io.vertx.ext.web.RoutingContext;
2425
import org.junit.Test;
2526

27+
import java.io.IOException;
2628
import java.util.function.Consumer;
2729

2830
/**
@@ -743,4 +745,46 @@ public void testHierarchicalWithParamsSimpleWithDummy() throws Exception {
743745

744746
testRequest(HttpMethod.GET, "/rest/product/123/bar", 200, "OK");
745747
}
748+
749+
@Test
750+
public void testSetExceptionHandler() throws Exception {
751+
Router restRouter = Router.router(vertx);
752+
Router productRouter = Router.router(vertx);
753+
Router instanceRouter = Router.router(vertx);
754+
755+
router.route("/rest*").subRouter(restRouter);
756+
restRouter.route("/product*").subRouter(productRouter);
757+
productRouter.route("/:id*").subRouter(instanceRouter);
758+
instanceRouter.get("/:foo").handler(ctx -> {
759+
if ("ex".equals(ctx.pathParam("foo"))) {
760+
throw new RuntimeException("ouch!");
761+
}
762+
ctx.response().end();
763+
});
764+
765+
HttpClientResponse response = requestGet("/rest/product/123/ex").await();
766+
assertEquals(500, response.statusCode());
767+
assertEquals("Internal Server Error", response.body().await().toString());
768+
769+
assertRouterErrorHandlers("root", router, 500, "/rest/product/123/ex");
770+
assertRouterErrorHandlers("root", router, 404, "/rest/product/123/foo/404");
771+
772+
assertRouterErrorHandlers("rest", restRouter, 500, "/rest/product/123/ex");
773+
assertRouterErrorHandlers("rest", restRouter, 404, "/rest/product/123/foo/404");
774+
775+
assertRouterErrorHandlers("product", productRouter, 500, "/rest/product/123/ex");
776+
assertRouterErrorHandlers("product", productRouter, 404, "/rest/product/123/foo/404");
777+
778+
assertRouterErrorHandlers("instance", instanceRouter, 500, "/rest/product/123/ex");
779+
assertRouterErrorHandlers("instance", instanceRouter, 404, "/rest/product/123/foo/404");
780+
}
781+
782+
private void assertRouterErrorHandlers(String name, Router router, int statusCode, String path) {
783+
String handlerKey = name + "." + statusCode + ".errorHandler";
784+
router.errorHandler(statusCode, ctx -> ctx.response().setStatusCode(statusCode).end(handlerKey));
785+
786+
HttpClientResponse response = requestGet(path).await();
787+
assertEquals(statusCode, response.statusCode());
788+
assertEquals(handlerKey, response.body().await().toString());
789+
}
746790
}

vertx-web/src/test/java/io/vertx/ext/web/tests/WebTestBase.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package io.vertx.ext.web.tests;
1818

1919
import io.netty.handler.codec.http.HttpResponseStatus;
20+
import io.vertx.core.Future;
2021
import io.vertx.core.buffer.Buffer;
2122
import io.vertx.core.http.*;
2223
import io.vertx.ext.web.Router;
@@ -317,4 +318,8 @@ public static void cleanupFileUploadDir() throws IOException {
317318
}
318319
}
319320

321+
public Future<HttpClientResponse> requestGet(String path) {
322+
RequestOptions options = new RequestOptions().setHost("localhost").setPort(server.actualPort()).setURI(path);
323+
return client.request(options).compose(HttpClientRequest::send).compose(resp -> resp.body().map(resp));
324+
}
320325
}

0 commit comments

Comments
 (0)