From 73d6dae47ba19e7e23099e73500114f86ce4c898 Mon Sep 17 00:00:00 2001 From: Thomas Segismont Date: Wed, 25 Oct 2023 17:11:54 +0200 Subject: [PATCH] Replace ISE with VertxException when failing context with informational message Related to #2486 Follows-up on #1857 ISE creates a stack trace which isn't really useful. In these cases, we only care about the message. This change makes the application log a single line (or more if the message is long). Besides, it saves the cost of creating the ISE stack trace. Signed-off-by: Thomas Segismont --- .../ext/web/handler/impl/BodyHandlerImpl.java | 3 ++- .../ext/web/handler/impl/CSRFHandlerImpl.java | 5 +++-- .../ext/web/handler/impl/CorsHandlerImpl.java | 3 ++- .../web/handler/impl/HotpAuthHandlerImpl.java | 5 +++-- .../web/handler/impl/JWTAuthHandlerImpl.java | 9 +++++---- .../web/handler/impl/OAuth2AuthHandlerImpl.java | 17 +++++++++-------- .../web/handler/impl/TotpAuthHandlerImpl.java | 5 +++-- .../web/handler/impl/WebAuthnHandlerImpl.java | 9 +++++---- .../sockjs/impl/RawWebSocketTransport.java | 4 ++-- .../handler/sockjs/impl/WebSocketTransport.java | 6 +++--- 10 files changed, 37 insertions(+), 29 deletions(-) diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/BodyHandlerImpl.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/BodyHandlerImpl.java index d9e9bcf267..f986820ecd 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/BodyHandlerImpl.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/BodyHandlerImpl.java @@ -20,6 +20,7 @@ import io.netty.handler.codec.http.HttpHeaderValues; import io.vertx.core.Future; import io.vertx.core.Handler; +import io.vertx.core.VertxException; import io.vertx.core.buffer.Buffer; import io.vertx.core.file.FileSystem; import io.vertx.core.http.HttpHeaders; @@ -132,7 +133,7 @@ public void handle(RoutingContext context) { .resume(); } else { String failure = "BodyHandler invoked after the request has ended. It should be the first handler invoked. Otherwise, you must pause the request after it's received."; - context.fail(new IllegalStateException(failure)); + context.fail(new VertxException(failure, true)); } } else { // on reroute we need to re-merge the form params if that was desired diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/CSRFHandlerImpl.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/CSRFHandlerImpl.java index ac48187ab2..77dcb29276 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/CSRFHandlerImpl.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/CSRFHandlerImpl.java @@ -18,6 +18,7 @@ import io.vertx.core.AsyncResult; import io.vertx.core.Handler; import io.vertx.core.Vertx; +import io.vertx.core.VertxException; import io.vertx.core.http.Cookie; import io.vertx.core.http.CookieSameSite; import io.vertx.core.http.HttpMethod; @@ -196,7 +197,7 @@ private boolean isValidRequest(RoutingContext ctx) { if (ctx.body().available()) { header = ctx.request().getFormAttribute(headerName); } else { - ctx.fail(new IllegalStateException("BodyHandler is required to process POST requests")); + ctx.fail(new VertxException("BodyHandler is required to process POST requests", true)); return false; } } @@ -304,7 +305,7 @@ public void handle(RoutingContext ctx) { // if we're being strict with the origin // ensure that they are always valid if (!Origin.check(origin, ctx)) { - ctx.fail(403, new IllegalStateException("Invalid Origin")); + ctx.fail(403, new VertxException("Invalid Origin", true)); return; } diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/CorsHandlerImpl.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/CorsHandlerImpl.java index 1b938687d0..2b20bf3977 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/CorsHandlerImpl.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/CorsHandlerImpl.java @@ -16,6 +16,7 @@ package io.vertx.ext.web.handler.impl; +import io.vertx.core.VertxException; import io.vertx.core.http.HttpMethod; import io.vertx.core.http.HttpServerRequest; import io.vertx.core.http.HttpServerResponse; @@ -250,7 +251,7 @@ public void handle(RoutingContext context) { .response() .setStatusMessage("CORS Rejected - Invalid origin"); context - .fail(403, new IllegalStateException("CORS Rejected - Invalid origin")); + .fail(403, new VertxException("CORS Rejected - Invalid origin", true)); } } diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/HotpAuthHandlerImpl.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/HotpAuthHandlerImpl.java index 215c96ea09..befbdbf32f 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/HotpAuthHandlerImpl.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/HotpAuthHandlerImpl.java @@ -16,6 +16,7 @@ package io.vertx.ext.web.handler.impl; import io.vertx.core.Future; +import io.vertx.core.VertxException; import io.vertx.core.http.HttpMethod; import io.vertx.core.json.JsonObject; import io.vertx.ext.auth.User; @@ -146,7 +147,7 @@ private void mountRegister() { .handler(ctx -> { final User user = ctx.user().get(); if (user == null || user.get("username") == null) { - ctx.fail(new IllegalStateException("User object misses 'username' attribute")); + ctx.fail(new VertxException("User object misses 'username' attribute", true)); return; } @@ -170,7 +171,7 @@ private void mountVerify() { .handler(ctx -> { final User user = ctx.user().get(); if (user == null || user.get("username") == null) { - ctx.fail(new IllegalStateException("User object misses 'username' attribute")); + ctx.fail(new VertxException("User object misses 'username' attribute", true)); return; } diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/JWTAuthHandlerImpl.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/JWTAuthHandlerImpl.java index 5550c85015..b977222f8d 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/JWTAuthHandlerImpl.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/JWTAuthHandlerImpl.java @@ -17,6 +17,7 @@ package io.vertx.ext.web.handler.impl; import io.vertx.core.Future; +import io.vertx.core.VertxException; import io.vertx.core.json.JsonObject; import io.vertx.ext.auth.User; import io.vertx.ext.auth.audit.Marker; @@ -119,7 +120,7 @@ public void postAuthentication(RoutingContext ctx) { final User user = ctx.user().get(); if (user == null) { // bad state - ctx.fail(403, new IllegalStateException("no user in the context")); + ctx.fail(403, new VertxException("no user in the context", true)); return; } // the user is authenticated, however the user may not have all the required scopes @@ -128,12 +129,12 @@ public void postAuthentication(RoutingContext ctx) { if (scopes.size() > 0) { final JsonObject jwt = user.get("accessToken"); if (jwt == null) { - ctx.fail(403, new IllegalStateException("Invalid JWT: null")); + ctx.fail(403, new VertxException("Invalid JWT: null", true)); return; } if (jwt.getValue("scope") == null) { - ctx.fail(403, new IllegalStateException("Invalid JWT: scope claim is required")); + ctx.fail(403, new VertxException("Invalid JWT: scope claim is required", true)); return; } @@ -150,7 +151,7 @@ public void postAuthentication(RoutingContext ctx) { if (target != null) { for (String scope : scopes) { if (!target.contains(scope)) { - ctx.fail(403, new IllegalStateException("JWT scopes != handler scopes")); + ctx.fail(403, new VertxException("JWT scopes != handler scopes", true)); return; } } diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/OAuth2AuthHandlerImpl.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/OAuth2AuthHandlerImpl.java index 62c8bfc7f6..df0939b0e0 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/OAuth2AuthHandlerImpl.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/OAuth2AuthHandlerImpl.java @@ -18,6 +18,7 @@ import io.vertx.core.Future; import io.vertx.core.Vertx; +import io.vertx.core.VertxException; import io.vertx.core.http.HttpHeaders; import io.vertx.core.http.HttpMethod; import io.vertx.core.impl.logging.Logger; @@ -342,7 +343,7 @@ public void postAuthentication(RoutingContext ctx) { final User user = ctx.user().get(); if (user == null) { // bad state - ctx.fail(403, new IllegalStateException("no user in the context")); + ctx.fail(403, new VertxException("no user in the context", true)); return; } @@ -368,12 +369,12 @@ public void postAuthentication(RoutingContext ctx) { (idx != 0 && userScopes.charAt(idx -1) != ' ') || (idx + scope.length() != userScopes.length() && userScopes.charAt(idx + scope.length()) != ' ')) { // invalid scope assignment - ctx.fail(403, new IllegalStateException("principal scope != handler scopes")); + ctx.fail(403, new VertxException("principal scope != handler scopes", true)); return; } } else { // invalid scope assignment - ctx.fail(403, new IllegalStateException("principal scope != handler scopes")); + ctx.fail(403, new VertxException("principal scope != handler scopes", true)); return; } } @@ -440,9 +441,9 @@ private void mountCallback() { String errorDescription = ctx.request().getParam("error_description"); if (errorDescription != null) { - ctx.fail(errorCode, new IllegalStateException(error + ": " + errorDescription)); + ctx.fail(errorCode, new VertxException(error + ": " + errorDescription, true)); } else { - ctx.fail(errorCode, new IllegalStateException(error)); + ctx.fail(errorCode, new VertxException(error, true)); } return; } @@ -452,7 +453,7 @@ private void mountCallback() { // code is a require value if (code == null) { - ctx.fail(400, new IllegalStateException("Missing code parameter")); + ctx.fail(400, new VertxException("Missing code parameter", true)); return; } @@ -468,7 +469,7 @@ private void mountCallback() { // state is a required field if (state == null) { - ctx.fail(400, new IllegalStateException("Missing IdP state parameter to the callback endpoint")); + ctx.fail(400, new VertxException("Missing IdP state parameter to the callback endpoint", true)); return; } @@ -482,7 +483,7 @@ private void mountCallback() { // if there's a state in the context they must match if (!state.equals(ctxState)) { // forbidden, the state is not valid (this is a replay attack) - ctx.fail(401, new IllegalStateException("Invalid oauth2 state")); + ctx.fail(401, new VertxException("Invalid oauth2 state", true)); return; } diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/TotpAuthHandlerImpl.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/TotpAuthHandlerImpl.java index 03ca23e059..d444ac5eae 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/TotpAuthHandlerImpl.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/TotpAuthHandlerImpl.java @@ -16,6 +16,7 @@ package io.vertx.ext.web.handler.impl; import io.vertx.core.Future; +import io.vertx.core.VertxException; import io.vertx.core.http.HttpMethod; import io.vertx.core.json.JsonObject; import io.vertx.ext.auth.User; @@ -144,7 +145,7 @@ private void mountRegister() { .handler(ctx -> { final User user = ctx.user().get(); if (user == null || user.get("username") == null) { - ctx.fail(new IllegalStateException("User object misses 'username' attribute")); + ctx.fail(new VertxException("User object misses 'username' attribute", true)); return; } final OtpKey key = otpKeyGen.generate(); @@ -169,7 +170,7 @@ private void mountVerify() { final User user = ctx.user().get(); if (user == null || user.get("username") == null) { - ctx.fail(new IllegalStateException("User object misses 'username' attribute")); + ctx.fail(new VertxException("User object misses 'username' attribute", true)); return; } diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/WebAuthnHandlerImpl.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/WebAuthnHandlerImpl.java index 5dd9ee27a8..4d7a85f71e 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/WebAuthnHandlerImpl.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/impl/WebAuthnHandlerImpl.java @@ -16,6 +16,7 @@ package io.vertx.ext.web.handler.impl; import io.vertx.core.Future; +import io.vertx.core.VertxException; import io.vertx.core.http.HttpMethod; import io.vertx.core.json.JsonObject; import io.vertx.ext.auth.User; @@ -31,8 +32,8 @@ import io.vertx.ext.web.handler.WebAuthnHandler; import io.vertx.ext.web.impl.OrderListener; import io.vertx.ext.web.impl.Origin; -import io.vertx.ext.web.impl.UserContextInternal; import io.vertx.ext.web.impl.RoutingContextInternal; +import io.vertx.ext.web.impl.UserContextInternal; public class WebAuthnHandlerImpl extends AuthenticationHandlerImpl implements WebAuthnHandler, OrderListener { @@ -204,7 +205,7 @@ private void mountRegister() { // input basic validation is OK if (session == null) { - ctx.fail(500, new IllegalStateException("No session or session handler is missing.")); + ctx.fail(500, new VertxException("No session or session handler is missing.", true)); return; } @@ -243,7 +244,7 @@ private void mountLogin() { // input basic validation is OK if (session == null) { - ctx.fail(500, new IllegalStateException("No session or session handler is missing.")); + ctx.fail(500, new VertxException("No session or session handler is missing.", true)); return; } @@ -293,7 +294,7 @@ private void mountResponse() { final Session session = ctx.session(); if (session == null) { - ctx.fail(500, new IllegalStateException("No session or session handler is missing.")); + ctx.fail(500, new VertxException("No session or session handler is missing.", true)); return; } diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/sockjs/impl/RawWebSocketTransport.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/sockjs/impl/RawWebSocketTransport.java index b6a3aa5f65..fa3ab34fc1 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/sockjs/impl/RawWebSocketTransport.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/sockjs/impl/RawWebSocketTransport.java @@ -47,7 +47,7 @@ import io.vertx.ext.web.handler.sockjs.SockJSSocket; import io.vertx.ext.web.impl.Origin; -import static io.vertx.core.http.HttpHeaders.*; +import static io.vertx.core.http.HttpHeaders.ALLOW; import static io.vertx.ext.web.impl.Utils.canUpgradeToWebsocket; /** @@ -83,7 +83,7 @@ private void handleGet(RoutingContext ctx) { } if (!Origin.check(origin, ctx)) { - ctx.fail(403, new IllegalStateException("Invalid Origin")); + ctx.fail(403, new VertxException("Invalid Origin", true)); return; } diff --git a/vertx-web/src/main/java/io/vertx/ext/web/handler/sockjs/impl/WebSocketTransport.java b/vertx-web/src/main/java/io/vertx/ext/web/handler/sockjs/impl/WebSocketTransport.java index a3cfc96ed0..eb155a1519 100644 --- a/vertx-web/src/main/java/io/vertx/ext/web/handler/sockjs/impl/WebSocketTransport.java +++ b/vertx-web/src/main/java/io/vertx/ext/web/handler/sockjs/impl/WebSocketTransport.java @@ -32,10 +32,10 @@ package io.vertx.ext.web.handler.sockjs.impl; -import io.vertx.core.AsyncResult; import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.Vertx; +import io.vertx.core.VertxException; import io.vertx.core.http.HttpServerRequest; import io.vertx.core.http.ServerWebSocket; import io.vertx.core.impl.logging.Logger; @@ -50,7 +50,7 @@ import io.vertx.ext.web.handler.sockjs.SockJSSocket; import io.vertx.ext.web.impl.Origin; -import static io.vertx.core.http.HttpHeaders.*; +import static io.vertx.core.http.HttpHeaders.ALLOW; import static io.vertx.ext.web.impl.Utils.canUpgradeToWebsocket; /** @@ -88,7 +88,7 @@ private void handleGet(RoutingContext ctx) { } if (!Origin.check(origin, ctx)) { - ctx.fail(403, new IllegalStateException("Invalid Origin")); + ctx.fail(403, new VertxException("Invalid Origin", true)); return; }