twitter / finatra

Fast, testable, Scala services built on TwitterServer and Finagle
https://twitter.github.io/finatra/
Apache License 2.0
2.27k stars 406 forks source link

Unhandled IllegalArgumentException when passing illegal URL characters #507

Closed szysas closed 4 years ago

szysas commented 5 years ago

Expected behavior

Defined Exception mapper should catch and translate exception.

Actual behavior

Server returns 500 error and print stack traces in logs

java.lang.IllegalArgumentException: unterminated escape sequence at index 19 of: illegal-characters-%%
    at io.netty.handler.codec.http.QueryStringDecoder.decodeComponent(QueryStringDecoder.java:349) ~[netty-codec-http-4.1.33.Final.jar:4.1.33.Final]
    at io.netty.handler.codec.http.QueryStringDecoder.decodeComponent(QueryStringDecoder.java:309) ~[netty-codec-http-4.1.33.Final.jar:4.1.33.Final]
    at io.netty.handler.codec.http.QueryStringDecoder.decodeComponent(QueryStringDecoder.java:280) ~[netty-codec-http-4.1.33.Final.jar:4.1.33.Final]
    at com.twitter.finatra.http.internal.routing.PathPattern.$anonfun$extractMatches$1(PathPattern.scala:61) ~[finatra-http_2.12-19.6.0.jar:19.6.0]
    at scala.collection.immutable.Stream.foreach(Stream.scala:533) ~[scala-library-2.12.8.jar:?]
    at com.twitter.finatra.http.internal.routing.PathPattern.extractMatches(PathPattern.scala:59) ~[finatra-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finatra.http.internal.routing.PathPattern.extract(PathPattern.scala:51) ~[finatra-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finatra.http.internal.routing.Route.handle(Route.scala:66) ~[finatra-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finatra.http.internal.routing.Routes.handle(Routes.scala:61) ~[finatra-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finatra.http.internal.routing.RoutingService.route(RoutingService.scala:35) ~[finatra-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finatra.http.internal.routing.RoutingService.apply(RoutingService.scala:30) ~[finatra-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finatra.http.internal.routing.RoutingService.apply(RoutingService.scala:11) ~[finatra-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.ServiceProxy.apply(ServiceProxy.scala:12) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.tracing.AnnotatingTracingFilter.apply(TraceInitializerFilter.scala:140) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.server.ThreadUsage$ThreadUsageFilter.apply(ThreadUsage.scala:129) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.tracing.ServerDestTracingFilter.apply(DestinationTracing.scala:38) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.service.DeadlineFilter.apply(DeadlineFilter.scala:265) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.filter.DtabStatsFilter.apply(DtabStatsFilter.scala:37) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.service.StatsFilter.apply(StatsFilter.scala:258) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.filter.ExceptionSourceFilter.apply(ExceptionSourceFilter.scala:50) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.filter.MkJvmFilter$$anon$1.apply(MkJvmFilter.scala:30) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.filter.ServerStatsFilter.apply(ServerStatsFilter.scala:55) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.tracing.AnnotatingTracingFilter.apply(TraceInitializerFilter.scala:140) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.filter.HttpNackFilter.apply(HttpNackFilter.scala:156) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.filter.HttpNackFilter.apply(HttpNackFilter.scala:113) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.filter.PayloadSizeFilter.apply(PayloadSizeFilter.scala:45) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.server.BackupRequest$$anon$1$$anon$2.apply(BackupRequest.scala:31) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.filter.ServerContextFilter.$anonfun$apply$1(ContextFilter.scala:15) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Local.let(Local.scala:4979) ~[util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.context.MarshalledContext.letLocal(MarshalledContext.scala:157) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.context.MarshalledContext.let(MarshalledContext.scala:104) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.codec.HttpContext$.read(HttpContext.scala:90) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.filter.ServerContextFilter.apply(ContextFilter.scala:15) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.filter.ServerContextFilter.apply(ContextFilter.scala:12) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:13) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.HttpServerTraceInitializer.$anonfun$make$3(HttpServerTraceInitializer.scala:20) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.TraceInfo$.$anonfun$letTraceIdFromRequestHeaders$1(TraceInfo.scala:58) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Local.let(Local.scala:4979) ~[util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.context.MarshalledContext.letLocal(MarshalledContext.scala:157) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.context.MarshalledContext.let(MarshalledContext.scala:90) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.tracing.Trace$.letId(Trace.scala:104) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.TraceInfo$.letTraceIdFromRequestHeaders(TraceInfo.scala:56) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.HttpServerTraceInitializer.$anonfun$make$2(HttpServerTraceInitializer.scala:20) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Local.let(Local.scala:4979) ~[util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.context.LocalContext.letLocal(LocalContext.scala:53) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.context.LocalContext.let(LocalContext.scala:24) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.tracing.Trace$.letTracer(Trace.scala:124) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.HttpServerTraceInitializer.$anonfun$make$1(HttpServerTraceInitializer.scala:20) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$16.apply(Filter.scala:406) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.filter.MonitorFilter.apply(MonitorFilter.scala:66) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.filter.DtabFilter.apply(DtabFilter.scala:25) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.filter.DtabFilter.apply(DtabFilter.scala:12) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.filter.StreamingStatsFilter.apply(StreamingStatsFilter.scala:131) ~[finagle-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.filter.StreamingStatsFilter.apply(StreamingStatsFilter.scala:92) ~[finagle-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Service$$anon$1.apply(Service.scala:16) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.codec.ResponseConformanceFilter$.apply(ResponseConformanceFilter.scala:23) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.codec.ResponseConformanceFilter$.apply(ResponseConformanceFilter.scala:18) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.Filter$$anon$1.apply(Filter.scala:93) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.codec.HttpServerDispatcher.dispatch(HttpServerDispatcher.scala:44) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.codec.HttpServerDispatcher.dispatch(HttpServerDispatcher.scala:20) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.exp.GenStreamingSerialServerDispatcher.$anonfun$dispatchAndHandleFn$2(GenStreamingSerialServerDispatcher.scala:79) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Local.let(Local.scala:4979) ~[util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.context.LocalContext.letLocal(LocalContext.scala:53) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.context.LocalContext.let(LocalContext.scala:24) ~[finagle-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.http.exp.GenStreamingSerialServerDispatcher.$anonfun$dispatchAndHandleFn$1(GenStreamingSerialServerDispatcher.scala:77) ~[finagle-base-http_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Future.$anonfun$flatMap$1(Future.scala:1808) ~[util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Promise$FutureTransformer.liftedTree1$1(Promise.scala:250) ~[util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Promise$FutureTransformer.k(Promise.scala:250) ~[util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Promise$Transformer.apply(Promise.scala:225) ~[util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Promise$WaitQueue.com$twitter$util$Promise$WaitQueue$$run(Promise.scala:101) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Promise$WaitQueue$$anon$1.run(Promise.scala:96) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.concurrent.LocalScheduler$Activation.run(Scheduler.scala:198) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.concurrent.LocalScheduler$Activation.submit(Scheduler.scala:157) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.concurrent.LocalScheduler.submit(Scheduler.scala:274) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.concurrent.Scheduler$.submit(Scheduler.scala:109) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Promise$WaitQueue.runInScheduler(Promise.scala:96) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Promise.updateIfEmpty(Promise.scala:797) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Promise.update(Promise.scala:769) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.util.Promise.setValue(Promise.scala:745) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.concurrent.AsyncQueue.offer(AsyncQueue.scala:123) [util-core_2.12-19.6.0.jar:19.6.0]
    at com.twitter.finagle.netty4.transport.ChannelTransport$$anon$2.channelRead(ChannelTransport.scala:168) [finagle-netty4_2.12-19.6.0.jar:19.6.0]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at com.twitter.finagle.netty4.channel.ChannelRequestStatsHandler.channelRead(ChannelRequestStatsHandler.scala:48) [finagle-netty4_2.12-19.6.0.jar:19.6.0]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at com.twitter.finagle.netty4.http.handler.UnpoolHttpHandler$.channelRead(UnpoolHttpHandler.scala:32) [finagle-netty4-http_2.12-19.6.0.jar:19.6.0]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at com.twitter.finagle.netty4.http.handler.BadRequestHandler.channelRead(BadRequestHandler.scala:41) [finagle-netty4-http_2.12-19.6.0.jar:19.6.0]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at com.twitter.finagle.netty4.http.handler.HeaderValidatorHandler$.channelRead(HeaderValidatorHandler.scala:51) [finagle-netty4-http_2.12-19.6.0.jar:19.6.0]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at com.twitter.finagle.netty4.http.handler.UriValidatorHandler$.channelRead(UriValidatorHandler.scala:29) [finagle-netty4-http_2.12-19.6.0.jar:19.6.0]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) [netty-codec-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) [netty-codec-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:102) [netty-codec-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111) [netty-codec-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:323) [netty-codec-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:297) [netty-codec-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at com.twitter.finagle.netty4.channel.ChannelStatsHandler.channelRead(ChannelStatsHandler.scala:155) [finagle-netty4_2.12-19.6.0.jar:19.6.0]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:352) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1408) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:374) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:360) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:930) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:163) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:682) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:617) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:534) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:496) [netty-transport-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:906) [netty-common-4.1.35.Final.jar:4.1.35.Final]
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) [netty-common-4.1.35.Final.jar:4.1.35.Final]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_212]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_212]
    at com.twitter.finagle.util.BlockingTimeTrackingThreadFactory$$anon$1.run(BlockingTimeTrackingThreadFactory.scala:23) [finagle-core_2.12-19.6.0.jar:19.6.0]
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) [netty-common-4.1.35.Final.jar:4.1.35.Final]
    at java.lang.Thread.run(Thread.java:748) [?:1.8.0_212]

Steps to reproduce the behavior

Finatra 19.6.0; HttpServer with simple configuration:

override def configureHttp(router: HttpRouter) {
    router
      .filter[ExceptionMappingFilter[Request]]
      .add[RestAPIController]
      .exceptionMapper[IllegalArgumentExceptionMapper]
  }
@Singleton
class IllegalArgumentExceptionMapper extends ExceptionMapper[IllegalArgumentException] {

  override def toResponse(request: Request, throwable: IllegalArgumentException): Response = Response(Status.BadRequest)
}

Make request with illegal URl request, for example GET /test/test%%

mosesn commented 5 years ago

Thanks for the bug report @szysas! You would expect it to instead return some kind of 4xx? It sounds like maybe the move would be to add something to the QueryStringDecoder to throw a more specific exception and then add something to the default exception mapper to catch that exception and turn it into the appropriate error code?

cacoco commented 5 years ago

@szysas looks like this is happening before we can route the request which then doesn't trigger the exception mapping filter, the code blows up before executing the service wrapped with the filter. That's unfortunate. We'll take a look and see what we can do. Thanks for reporting.

cacoco commented 4 years ago

@szysas the workaround is to ensure you add the ExceptionMappingFilter with beforeRouting = true, e.g.,

router
  .filter(new ExceptionMappingFilter[Request](injector.instance[ExceptionManager]), beforeRouting = true)

We're looking at ways we could potentially help here but we're not likely to make this case configurable in that we'd most likely always return a 400 - BadRequest in this instance.

szysas commented 4 years ago

👍