Uploaded image for project: 'RESTEasy'
  1. RESTEasy
  2. RESTEASY-3118

Reactor Netty ReactorNettyHttpResponse invokes the setStatus sometimes after the headers are committed

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Major Major
    • None
    • None
    • Netty integration
    • None

      The StreamingOutputTest seems to be hanging and failing more regularly on CI. After adding some debug logging the error seems to be:

      17:09:47,383 ERROR [org.jboss.resteasy.resteasy_jaxrs.i18n] (Thread-10) RESTEASY002020: Unhandled asynchronous exception, sending back 500: org.jboss.resteasy.spi.UnhandledException: java.lang.IllegalStateException: Status and headers already sent
         at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:230)
         at org.jboss.resteasy.core.SynchronousDispatcher.asynchronousExceptionDelivery(SynchronousDispatcher.java:575)
         at org.jboss.resteasy.core.AbstractAsynchronousResponse.internalResume(AbstractAsynchronousResponse.java:240)
         at org.jboss.resteasy.core.AbstractAsynchronousResponse.internalResume(AbstractAsynchronousResponse.java:222)
         at org.jboss.resteasy.plugins.server.reactor.netty.ReactorNettyHttpRequest$NettyExecutionContext$NettyHttpAsyncResponse.resume(ReactorNettyHttpRequest.java:302)
         at org.jboss.resteasy.test.AsyncJaxrsResource$4.run(AsyncJaxrsResource.java:145)
      Caused by: java.lang.IllegalStateException: Status and headers already sent
         at reactor.netty.http.server.HttpServerOperations.status(HttpServerOperations.java:459)
         at reactor.netty.http.server.HttpServerResponse.status(HttpServerResponse.java:206)
         at org.jboss.resteasy.plugins.server.reactor.netty.ReactorNettyHttpResponse.setStatus(ReactorNettyHttpResponse.java:59)
         at org.jboss.resteasy.core.ServerResponseWriter.lambda$writeNomapResponse$3(ServerResponseWriter.java:139)
         at org.jboss.resteasy.core.interception.jaxrs.ContainerResponseContextImpl.filter(ContainerResponseContextImpl.java:404)
         at org.jboss.resteasy.core.ServerResponseWriter.executeFilters(ServerResponseWriter.java:261)
         at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:101)
         at org.jboss.resteasy.core.ServerResponseWriter.writeNomapResponse(ServerResponseWriter.java:74)
         at org.jboss.resteasy.core.SynchronousDispatcher.writeException(SynchronousDispatcher.java:226)
         ... 5 more
      
      17:09:47,384 ERROR [org.jboss.resteasy.test.AsyncJaxrsResource] (Thread-10) Status and headers already sent: java.lang.IllegalStateException: Status and headers already sent
         at reactor.netty.http.server.HttpServerOperations.status(HttpServerOperations.java:459)
         at reactor.netty.http.server.HttpServerResponse.status(HttpServerResponse.java:206)
         at org.jboss.resteasy.plugins.server.reactor.netty.ReactorNettyHttpResponse.sendError(ReactorNettyHttpResponse.java:240)
         at org.jboss.resteasy.core.SynchronousDispatcher.unhandledAsynchronousException(SynchronousDispatcher.java:555)
         at org.jboss.resteasy.core.SynchronousDispatcher.asynchronousExceptionDelivery(SynchronousDispatcher.java:584)
         at org.jboss.resteasy.core.AbstractAsynchronousResponse.internalResume(AbstractAsynchronousResponse.java:240)
         at org.jboss.resteasy.core.AbstractAsynchronousResponse.internalResume(AbstractAsynchronousResponse.java:222)
         at org.jboss.resteasy.plugins.server.reactor.netty.ReactorNettyHttpRequest$NettyExecutionContext$NettyHttpAsyncResponse.resume(ReactorNettyHttpRequest.java:302)
         at org.jboss.resteasy.test.AsyncJaxrsResource$4.run(AsyncJaxrsResource.java:145)
      
      Terminate batch job (Y/N)? 
      ##[error]The operation was canceled.
      

      This seems to be mostly happen on Windows. However, it fails on Linux from time to time as well.

      One solution might be in the ReactorNettyHttpResponse.setStatus() to do something like:

      @Override
      public void setStatus(int status) {
          if (!resp.hasSentHeaders()) {
              resp.status(status);
          } else {
              throw new IllegalStateException(Messages.MESSAGES.alreadyCommitted());
          }
      }
      

      However, that just kind of hides the actual error. It would stop the potential deadlock though. The real cause needs to be determined.

            rsearls r searls
            jperkins-rhn James Perkins
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: