{"action":"opened","issue":{"url":"https://api.github.com/repos/vert-x3/vertx-web/issues/225","labels_url":"https://api.github.com/repos/vert-x3/vertx-web/issues/225/labels{/name}","comments_url":"https://api.github.com/repos/vert-x3/vertx-web/issues/225/comments","events_url":"https://api.github.com/repos/vert-x3/vertx-web/issues/225/events","html_url":"https://github.com/vert-x3/vertx-web/issues/225","id":111785683,"number":225,"title":"Improper error handling in Router","user":{"login":"meshcow","id":10828974,"avatar_url":"https://avatars.githubusercontent.com/u/10828974?v=3","gravatar_id":"","url":"https://api.github.com/users/meshcow","html_url":"https://github.com/meshcow","followers_url":"https://api.github.com/users/meshcow/followers","following_url":"https://api.github.com/users/meshcow/following{/other_user}","gists_url":"https://api.github.com/users/meshcow/gists{/gist_id}","starred_url":"https://api.github.com/users/meshcow/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/meshcow/subscriptions","organizations_url":"https://api.github.com/users/meshcow/orgs","repos_url":"https://api.github.com/users/meshcow/repos","events_url":"https://api.github.com/users/meshcow/events{/privacy}","received_events_url":"https://api.github.com/users/meshcow/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":0,"created_at":"2015-10-16T08:28:22Z","updated_at":"2015-10-16T08:28:22Z","closed_at":null,"body":"Hi,\r\n\r\nThe server code:\r\n```java\r\nimport io.vertx.core.Vertx;\r\nimport io.vertx.ext.web.Router;\r\n\r\npublic class TestServer {\r\n\r\n    public static void main(String[] args) {\r\n        Vertx vertx=Vertx.vertx();\r\n        Router router = Router.router(vertx);\r\n        router.exceptionHandler(throwable -> {\r\n            System.err.println(\"router failure\");\r\n            throwable.printStackTrace();\r\n        });\r\n        router.route().handler(ctx -> ctx.response().end(\"ok\"));\r\n        vertx.createHttpServer().requestHandler(router::accept).listen(8080);\r\n    }\r\n}\r\n```\r\nwith a request like below \r\n```bash\r\n$ curl -XDEBUG http://localhost:8080/\r\n```\r\ncauses the following at the server side\r\n```java\r\nOct 16, 2015 10:42:33 AM io.vertx.core.impl.ContextImpl\r\nSEVERE: Unhandled exception\r\njava.lang.IllegalArgumentException: No enum constant io.vertx.core.http.HttpMethod.DEBUG\r\n\tat java.lang.Enum.valueOf(Enum.java:238)\r\n\tat io.vertx.core.http.HttpMethod.valueOf(HttpMethod.java:26)\r\n\tat io.vertx.core.http.impl.HttpServerRequestImpl.method(HttpServerRequestImpl.java:124)\r\n\tat io.vertx.ext.web.impl.HttpServerRequestWrapper.<init>(HttpServerRequestWrapper.java:21)\r\n\tat io.vertx.ext.web.impl.RoutingContextImplBase.<init>(RoutingContextImplBase.java:45)\r\n\tat io.vertx.ext.web.impl.RoutingContextImpl.<init>(RoutingContextImpl.java:59)\r\n\tat io.vertx.ext.web.impl.RouterImpl.accept(RouterImpl.java:79)\r\n\tat TestServer$$Lambda$7/1772160903.handle(Unknown Source)\r\n\tat io.vertx.core.http.impl.ServerConnection.handleRequest(ServerConnection.java:274)\r\n\tat io.vertx.core.http.impl.ServerConnection.processMessage(ServerConnection.java:392)\r\n\tat io.vertx.core.http.impl.ServerConnection.handleMessage(ServerConnection.java:134)\r\n\tat io.vertx.core.http.impl.HttpServerImpl$ServerHandler.lambda$createConnAndHandle$25(HttpServerImpl.java:547)\r\n\tat io.vertx.core.http.impl.HttpServerImpl$ServerHandler$$Lambda$11/1773568813.run(Unknown Source)\r\n\tat io.vertx.core.impl.ContextImpl.lambda$wrapTask$16(ContextImpl.java:333)\r\n\tat io.vertx.core.impl.ContextImpl$$Lambda$12/5035501.run(Unknown Source)\r\n\tat io.vertx.core.impl.ContextImpl.executeFromIO(ContextImpl.java:225)\r\n\tat io.vertx.core.http.impl.HttpServerImpl$ServerHandler.createConnAndHandle(HttpServerImpl.java:545)\r\n\tat io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:479)\r\n\tat io.vertx.core.http.impl.HttpServerImpl$ServerHandler.doMessageReceived(HttpServerImpl.java:430)\r\n\tat io.vertx.core.http.impl.VertxHttpHandler.channelRead(VertxHttpHandler.java:85)\r\n\tat io.vertx.core.net.impl.VertxHandler.channelRead(VertxHandler.java:124)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)\r\n\tat io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:244)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:308)\r\n\tat io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:294)\r\n\tat io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:846)\r\n\tat io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)\r\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)\r\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)\r\n\tat io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)\r\n\tat io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)\r\n\tat io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:112)\r\n\tat java.lang.Thread.run(Thread.java:745)\r\n```\r\nThe connection remains open, so the client waits until times out. \r\nNote that registered exception handler is not called in this case. However, even if it was called, there is not much can be done as it provides only Throwable as an input and no means to respond to the client or control the further flow in other way.\r\n\r\nTried that with both 3.0.0 & 3.1.0, the behavior was the same.\r\n\r\nSo, in addition to this missing enum value bug, what I would like to be considered is improving a bit the error handling logic. I mean, what I would expect is that the router in cases like given one:\r\n- closes the underlying connection and recovers itself from the error\r\n- informs of a trouble through exceptionHandler() and provides it in addition to the Throwable a kind of ErrorContext which contains all bytes read so far, and some connection metainfo which can be then nicely logged for further analysis. This ErrorContext could actually provide some means to send error response back (before connection gets closed by the router, ofc).\r\n\r\nThanks\r\n"}}