How do I set the exceptionHandler for ConnectionBase on a HttpServer?

382 views
Skip to first unread message

Peter Leondires

unread,
Jun 14, 2018, 12:53:01 PM6/14/18
to vert.x

I am trying to configure my HttpServer to respond to bad content lengths with a response code of 400. When testing my server using the given curl command : curl -i -X POST -H "Content-Length: bad-length" http://localhost:9992/monitoring/status  I get an empty reply from the server: "curl: (52) Empty reply from server".  The below exception appears in the logs. I understand that the netty HttpUtil will always throw the NumberFormatException for a bad content-length, but is there a way I can define an exception handler to return my own response?

ERROR io.vertx.core.net.impl.ConnectionBase - Unhandled exception
java.lang.NumberFormatException: For input string: "bad-length"
    at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[?:1.8.0_171]
    at java.lang.Long.parseLong(Long.java:589) ~[?:1.8.0_171]
    at java.lang.Long.parseLong(Long.java:631) ~[?:1.8.0_171]
    at io.netty.handler.codec.http.HttpUtil.getContentLength(HttpUtil.java:178) ~[gateway-vertx.jar:?]
    at io.netty.handler.codec.http.HttpObjectDecoder.contentLength(HttpObjectDecoder.java:635) ~[gateway-vertx.jar:?]
    at io.netty.handler.codec.http.HttpObjectDecoder.readHeaders(HttpObjectDecoder.java:625) ~[gateway-vertx.jar:?]
    at io.netty.handler.codec.http.HttpObjectDecoder.decode(HttpObjectDecoder.java:227) ~[gateway-vertx.jar:?]
    at io.netty.handler.codec.ByteToMessageDecoder.decodeRemovalReentryProtection(ByteToMessageDecoder.java:489) ~[gateway-vertx.jar:?]
    at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:428) ~[gateway-vertx.jar:?]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) ~[gateway-vertx.jar:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[gateway-vertx.jar:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[gateway-vertx.jar:?]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[gateway-vertx.jar:?]
    at io.vertx.core.http.impl.Http1xOrH2CHandler.end(Http1xOrH2CHandler.java:60) ~[gateway-vertx.jar:?]
    at io.vertx.core.http.impl.Http1xOrH2CHandler.channelRead(Http1xOrH2CHandler.java:38) ~[gateway-vertx.jar:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[gateway-vertx.jar:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[gateway-vertx.jar:?]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[gateway-vertx.jar:?]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1414) ~[gateway-vertx.jar:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[gateway-vertx.jar:?]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[gateway-vertx.jar:?]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:945) ~[gateway-vertx.jar:?]
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:146) ~[gateway-vertx.jar:?]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) ~[gateway-vertx.jar:?]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) ~[gateway-vertx.jar:?]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) ~[gateway-vertx.jar:?]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) ~[gateway-vertx.jar:?]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) ~[gateway-vertx.jar:?]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [gateway-vertx.jar:?]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_171]

Below is an example code snippet from my verticle that creates the HttpServer.

    @Override
    public void start(Future<Void> startFuture) throws Exception {
        // Configure router
        Router router = Router.router(vertx);
        router.exceptionHandler(this::defaultExceptionHandler);
        vertx.exceptionHandler(this::defaultExceptionHandler);

        MonitoringApi monitoringApi = new MonitoringApi(vertx);
        router.mountSubRouter("/monitoring", monitoringApi.getRouter());

        // Start server
        int port = config().getInteger("monitoring.port");
        vertx.createHttpServer()
                .exceptionHandler(this::defaultExceptionHandler)
                .requestHandler(router::accept)
                .listen(port, res -> {
                    if (res.succeeded()) {
                        logger.debug("Started on port {}", port);
                        startFuture.complete();
                    } else {
                        startFuture.fail(res.cause());
                    }
                });
    }

    private void defaultExceptionHandler(Throwable throwable) {
        logger.error("Caught throwable", throwable);
    }

Thank you!

Grey Seal

unread,
Jun 15, 2018, 1:24:50 AM6/15/18
to vert.x
How about registering a failureHandler and then whenever an exception happens, call the fail method of RoutingContext. Something like this

router.route(CONTEXT_PATH + "/*").last().failureHandler(ErrorHandler.create(vertx));
routingContext.fail(ex);

You can have a look here:

Julien Viet

unread,
Jun 15, 2018, 1:56:56 AM6/15/18
to ve...@googlegroups.com
Hi,

the server exception handler will catch any issue that happens before the server is able to identity the connection (i.e it could be an http/1.1 connection or an http/2 connection), so before the first http request.

then once the http connection has been created (there is a connection handler on http server), you can catch there errors on the http connection exception handler).

so you should set an the handler on the server and the http connection to catch all cases.

Julien

--
You received this message because you are subscribed to the Google Groups "vert.x" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vertx+un...@googlegroups.com.
Visit this group at https://groups.google.com/group/vertx.
To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/39977cc1-13e7-41a1-abeb-556a57ca3cb1%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Peter Leondires

unread,
Jun 15, 2018, 9:25:05 AM6/15/18
to vert.x
@Grey Seal - Unfortunately that did not work for this case.


@Julien I was able to catch the exception by creating a connectionHandler like so:

.connectionHandler(conn -> {
            conn.exceptionHandler((error) -> {
                logger.error("Connection error", error);
            });
        })

Is there a way that I can return a response from this point without using goAway (it's an http/1.1 connection)?

thanks!
Peter

Julien Viet

unread,
Jun 15, 2018, 10:07:01 AM6/15/18
to ve...@googlegroups.com
that's not really possible now.

we could have a netSocket() method on HttpConnection that allows to do low level things like you describe (i.e send a response and close).

we already have it on HttpServerResponse.

Peter Leondires

unread,
Jun 15, 2018, 10:14:31 AM6/15/18
to vert.x

Okay, thanks for the info. I will just log the error for now.

Juan Martinez

unread,
Feb 17, 2022, 8:44:35 AM2/17/22
to vert.x
Hello,

Any news on this topic ? There's a way to customize http response/code on HttpServer exceptions ?

Thanks in advance for your help !

Julien Viet

unread,
Feb 19, 2022, 5:07:51 AM2/19/22
to vert.x
there are various handlers to catch events (and sometimes respond) you
can set since,

what are you trying to achieve ?
> To view this discussion on the web, visit https://groups.google.com/d/msgid/vertx/3c957a9b-ba9a-47d6-a5bb-ca859acdea19n%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages