There also appears to be a bug/inconsistency in the Chain of Resolvers in that it states
null
if the exception remains unresolved, for subsequent resolvers to try, and, if the exception remains at the end, it is allowed to bubble up to the Servlet container.
But returning null instead of error/500
gives me a 0-byte content. I was expecting null
to forward up to the default handlers one of which is to render src/main/resources/error/500.html
which occurs when I don't have an @ExceptionHandler
but it didn't work so I basically had to check if it is an HTML request and route accordingly
@ControllerAdvice
public class GeneralExceptionHandler implements Ordered {
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
@ExceptionHandler(Throwable.class)
public Object handleException(@NotNull Throwable e, @NotNull final WebRequest request) {
final var acceptHeader = request.getHeader(HttpHeaders.ACCEPT);
var isHtmlRequest = false;
if (acceptHeader != null) {
isHtmlRequest = Arrays.asList(acceptHeader.split(",")).contains(MediaType.TEXT_HTML_VALUE);
}
if (isHtmlRequest) {
return "error/500"; // ideally a return `null` should work as expected here.
} else {
return ResponseEntity.internalServerError()
.body(
StatusProto.fromThrowable(
io.grpc.Status.INTERNAL
.withDescription(e.getMessage())
.withCause(e)
.asRuntimeException()));
}
}
}
Ref: https://stackoverflow.com/questions/77176531/how-do-i-allow-for-500-html-to-be-used-in-spring-boot-only-when-the-request-was/77182791#77182791
Comment From: bclozel
This is the expected behavior.
This documentation snippet is about the chain of HandlerExceptionResolver
. The list of resolver is defined just above this section. The actual behavior @ExceptionHandler
method is implemented by ExceptionHandlerExceptionResolver
and explained in the dedicated section.