With the upgrade to Spring Boot 3.2.0-RC2 I think there is the following regression bug:

When a user visits an application, with ProblemDetail support enabled, with a browser and asking for HTML, then Spring should return the standard HTML error page instead of returning a ProblemDetail JSON or XML when static resource does not exist. This would particularly be important for applications that both serve a browser frontend as well as a REST API.

  • Spring Boot 3.1.5

Spring 404 on static resource does not return HTML error page

  • Spring Boot 3.2.0-RC2

Spring 404 on static resource does not return HTML error page

Related issues: - https://github.com/spring-projects/spring-framework/issues/29491 - https://github.com/spring-projects/spring-framework/issues/30930

NOTE: Attached is an example sb3-rest-webmvc.zip

Comment From: juliojgd

@rstoyanchev any chance this can be triaged/checked before 3.2.0 release?

Comment From: bclozel

I've had a look and reproduced the problem. This is an unfortunate consequence of #29491 and #30930 which is really a disconnect between the evolution of error handling and problem details here in Spring Framework, and how things are done in Spring Boot. There are already some inconsistencies (see https://github.com/spring-projects/spring-boot/issues/33885) and we'd like to revisit the error handling support in Spring Boot with https://github.com/spring-projects/spring-boot/issues/19525. Unfortunately, I don't see how we can solve this before the Spring Boot 3.2 release due this week.

I'm leaving this issue opened for now to discuss that in the Spring Framework team first, but I think the changes should happen ultimately in Spring Boot.

Comment From: tobias-lippert

Hi Spring Team, I tried to update to Spring Boot 3.2 today but this regression seems to block our upgrade. We use a custom ErrorControllerthat returns a custom response. The client uses the response to determine that an error page should be shown.

Using the global exception handler to handle the NoResourceFoundExceptionfails because it results in an ambiguous @ExceptionHandler 1. Is there any known workaround? 2. Is it likely that this will be fixed with the next patch release?

Comment From: bclozel

Here is a workaround for this issue: declare the following bean in your application:

import org.springframework.core.annotation.Order;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.resource.NoResourceFoundException;

@ControllerAdvice
@Order(-1)
class NoResourceFoundExceptionHandler {

    @ExceptionHandler(NoResourceFoundException.class)
    public final ResponseEntity<Object> handleResourceNotFound(Exception ex) throws Exception {
        throw ex;
    }

}

Comment From: rstoyanchev

Or alternatively, provide your own ResponseEntityExceptionHandler:

@ControllerAdvice
public class ProblemDetailsExceptionHandler extends ResponseEntityExceptionHandler {

    @Override
    protected ResponseEntity<Object> handleNoResourceFoundException(
            NoResourceFoundException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) {

        // If exception handling fails, processing of original exception continues 
        throw new IllegalStateException();
    }
}

Comment From: rstoyanchev

Before RFC 7807 we could not have an opinion in Spring Framework on the format of an error response, and could only have the abstract ResponseEntityExceptionHandler that does most of the work except the body format. Now that we are able to fill in that blank, it becomes more feasible to handle all exceptions within Spring MVC rather than letting them escape to Boot's error handling.

29491 and #30930 bring static resource exceptions into the fold, by having those handled within Spring MVC like other internal exceptions. However, ResponseEntityExceptionHandler only supports REST API responses. We would need an alternative that also can handle requests from browsers. The issue is there is currently no good way to create exception handler method variants with ResponseEntity or ModelAndView depending on the requested content type, which is what Boot's error mechanism does by handling ERROR dispatches in BasicErrorController with @RequestMapping methods. We should consider adding a produces attribute to @ExceptionHandler.

Comment From: tobias-lippert

@bclozel I've applied your proposed workaround today and it seems to resolve all our problems. Thanks for the quick fix. 😄

Comment From: bclozel

Closing this issue in favor of #31936 on the Framework side, https://github.com/spring-projects/spring-boot/issues/33885 and https://github.com/spring-projects/spring-boot/issues/19525 for Spring Boot support.