Spring-boot: ErrorPageFilter ignores REST response in case of Exception

Created on 30 Mar 2015  路  12Comments  路  Source: spring-projects/spring-boot

I'm running a Spring Boot web app with Thymeleaf + Spring MVC with a mix of MVC and REST calls (from JS code).
In a @ControllerAdvice I have the following exception handling code :

@ExceptionHandler(MyRuntimeException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public @ResponseBody MyRestResponse handleMyRuntimeException(MyRuntimeException exception) {
    return new MyRestResponse("Some data I want to send back to the client.");
}

Running Spring Boot with Tomcat embedded container I receive a MyRestResponse object in my ajax failure handler as expected but when I deploy in standalone Tomcat the response is ignored as the ErrorPageFilter forward the exception info instead due to the following code in doFilter() :

if (status >= 400) {
    handleErrorStatus(request, response, status, wrapped.getMessage());
    response.flushBuffer();
}

I went around the problem by writing directly the response to the output stream.

@ExceptionHandler(RuntimeException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public void handleRuntimeException(HttpServletRequest request, HttpServletResponse response, RuntimeException exception) {
        try {
            jacksonMessageConverter.write(new MyRestResult(translateMessage(exception)), MediaType.APPLICATION_JSON, new ServletServerHttpResponse(response));
            response.flushBuffer(); // Flush to commit the response
            } catch (IOException e) {
            e.printStackTrace();
        }
    }

That solution is ok for me but I think that should be possible to return a @ResponseBody in case of an error happening during a REST call.
I have also tried to return a ResponseEntity as suggested by @rstoyanchev here but still see the same issue.

blocker

Most helpful comment

There's some similarity with this question on Stackoverflow. In this question the output stream is being flushed by Jackson. This prevents the error page filter from performing the forward but it logs an error message:

2015-04-13 10:44:07.104 ERROR 30884 --- [nio-8080-exec-1] o.s.boot.context.web.ErrorPageFilter     : Cannot forward to error page for request [/5] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false

I think the error page filter needs some way of knowing that the error's already been handled and that it does not need to forward to an error page.

All 12 comments

There's some similarity with this question on Stackoverflow. In this question the output stream is being flushed by Jackson. This prevents the error page filter from performing the forward but it logs an error message:

2015-04-13 10:44:07.104 ERROR 30884 --- [nio-8080-exec-1] o.s.boot.context.web.ErrorPageFilter     : Cannot forward to error page for request [/5] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false

I think the error page filter needs some way of knowing that the error's already been handled and that it does not need to forward to an error page.

I have the same problem using spring-boot-starter-web but excluding @EnableAutoConfiguration(exclude = {WebMvcAutoConfiguration.class, ErrorMvcAutoConfiguration.class}).

I don't provide any html or direct servlet access, just provide soap + rest services.

As a result I'm getting the following error frequently when I return an @WebFault:

[] 2015-05-21 15:32:01,272 ERROR o.s.b.c.w.ErrorPageFilter: Cannot forward to error page for request [/services/MySoapService] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false

Same problem here also. It's really just the ERROR level log message that's the annoying everything else is working perfectly. My service produces a lot of 404's and reluctant to move off of Spring Boot 1.2.1 until this gets resolved. I'm considering using the workaround provided by @damienpolegato to get past this since I would really like to jump onto 1.2.4 and not let a minor error log message hold me back! I'll be watching this issue and hope there's a fix for this in a future release.

Are there are other known workarounds for this?

i've just turn off the ErrorPageFilter logger:

<logger name="org.springframework.boot.context.web.ErrorPageFilter">
    <level value="OFF" />
</logger>

Ha...thanks @denistiago this is exactly what I did in the interim you just beat me to the punch posting it on here. I certainly couldn't hold back upgraded to latest Spring boot because of this pesky log issue. In any event, thanks for posting!

+1

I'd really prefer if ErrorPageFilter could be disabled via application properties. It seems lot of people don't need the filter.

@femidav I've created #3603 for you. Thanks for the suggestion.

i've just turn off the ErrorPageFilter logger:

<logger name="org.springframework.boot.context.web.ErrorPageFilter">
    <level value="OFF" />
</logger>

hello there can i ask where should i put this code block?

@pariaSadatHosseiny In a logback.xml or logback-spring.xml file. You could also configure it in application.properties using logging.level.org.springframework.boot.context.web.ErrorPageFilter=off

If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

@pariaSadatHosseiny In a logback.xml or logback-spring.xml file. You could also configure it in application.properties using logging.level.org.springframework.boot.context.web.ErrorPageFilter=off

If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

thank you for Your Answer .I have such kind of Error but i am thinking if use this code just i dont see the Exception in the Log but I dont Understand the Reason,isn't it?!

my Error Is here :

2019-07-14 22:40:33 99839 [qtp1599771323-21] ERROR o.s.b.context.web.ErrorPageFilter - Cannot forward to error page for request [/vendor/jQuery/jquery.js] as the response has already been committed. As a result, the response may have the wrong status code. If your application is running on WebSphere Application Server you may be able to resolve this problem by setting com.ibm.ws.webcontainer.invokeFlushAfterService to false
org.eclipse.jetty.io.EofException: null
at org.eclipse.jetty.io.ChannelEndPoint.flush(ChannelEndPoint.java:284)

@pariaSadatHosseiny As I said above, if you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

Was this page helpful?
0 / 5 - 0 ratings