Juan Ma
Juan Ma

Reputation: 1

How to set custom error response/code on HttpServer exception?

I configured a vertx HttpServer (with the respective exceptionHandler) :

    webServer
        .requestHandler(router)
        .connectionHandler(httpConnection -> LOGGER.trace("New http connection arrived on webserver, {0}", httpConnection))
        .exceptionHandler(throwable -> LOGGER.error("Exception on web server", throwable))
        .listen(...);

I also set some routes (and the respective errorHandler/failureHandler);

    router
        .errorHandler(502, rc -> LOGGER.debug("Bad gateway error"))
        .route()
        .failureHandler(rc -> {
          if (rc != null) {
            if (rc.failure() != null) {
              LOGGER.error(String.format("Error when processing request: %s", rc.failure()));
            if (rc.failure() instanceof SomeException exception) {
                    rc.response()
                        .setStatusCode(400)
                        .end("validation failed.");
  
                }
            }
            rc.next();
          }
        });

When I try to request an invalid route (for instance GET http:localhost:8080/[d%09f54d6eD:azerty) a 502 Bad Gateway is returned and I can see on the logs that the HttpServer exceptionHandler is called:

Exception on web server
stackTrace:
java.lang.IllegalArgumentException: invalid version format: F54D6ED:AZERTY HTTP/1.1
   at io.netty.handler.codec.http.HttpVersion.<init>(HttpVersion.java:120)
   at io.netty.handler.codec.http.HttpVersion.valueOf(HttpVersion.java:77)
   at io.vertx.core.http.impl.VertxHttpRequestDecoder.createMessage(VertxHttpRequestDecoder.java:35)
   at io.netty.handler.codec.http.HttpObjectDecoder.decode(HttpObjectDecoder.java:206)
   at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:501)
   at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:440)
   at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:276)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
   at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
   at io.vertx.core.http.impl.Http1xOrH2CHandler.end(Http1xOrH2CHandler.java:61)
   at io.vertx.core.http.impl.Http1xOrH2CHandler.channelRead(Http1xOrH2CHandler.java:38)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
   at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:357)
   at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:379)
   at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:365)
   at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
   ...

However I cannot return other status code different that 502. How can I customize this ? I saw on older posts but for the moment I don't have the answer

Upvotes: 0

Views: 501

Answers (1)

jcompetence
jcompetence

Reputation: 8393

Could you check inside the handler the type of exception and specify the response as you want? See example below:

https://vertx.io/docs/apidocs/io/vertx/ext/web/Route.html

failureHandler takes a Handler<RouteContext>. RouteContext has a method which returns a Throwable.

Throwable   failure()

If the context is being routed to failure handlers after a failure has been triggered by calling fail(Throwable) then this will return that throwable.

         Handler<RoutingContext> validationFailureHandler = (RoutingContext rc) -> {
                if (rc.failure() instanceof SomeException exception) {
                    rc.response()
                        .setStatusCode(400)
                        .end("validation failed.");
  
                }
            };

         router
        .route()
        .failureHandler(validationFailureHandler);

      

Upvotes: 1

Related Questions