fix: suppress SSE client-disconnect noise in GlobalExceptionHandler
All checks were successful
Build and publish Docker image / Build and push CPU image (push) Successful in 2m9s
Build and publish Docker image / Build and push GPU image (push) Successful in 3m0s

AsyncRequestNotUsableException is thrown when the SSE client disconnects
before the server finishes writing (normal: browser tab close, MCP
client reconnect). The catch-all handler was logging it at ERROR level
and then attempting to write a JSON ErrorResponse onto a text/event-stream
response that no longer had a converter, producing a second spurious
HttpMessageNotWritableException log entry.

Fix: add a dedicated @ExceptionHandler(AsyncRequestNotUsableException)
that logs at DEBUG only and returns void (no body).
This commit is contained in:
moze
2026-05-06 01:53:09 +02:00
parent e7a8aa95fc
commit cfb35b35c0

View File

@@ -18,8 +18,9 @@ import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.servlet.resource.NoResourceFoundException;
import org.springframework.web.context.request.async.AsyncRequestNotUsableException;
import org.springframework.web.server.ResponseStatusException;
/** Central translator from domain / validation exceptions to HTTP + {@link ErrorResponse} JSON. */
@RestControllerAdvice
@@ -98,6 +99,14 @@ public class GlobalExceptionHandler {
return status(HttpStatus.INTERNAL_SERVER_ERROR, ex);
}
// Client disconnected from an SSE stream before the server finished writing.
// This is normal (browser tab closed, MCP client reconnected, etc.) — log at DEBUG only
// and return nothing; the response socket is already gone.
@ExceptionHandler(AsyncRequestNotUsableException.class)
public void handleClientDisconnect(AsyncRequestNotUsableException ex) {
log.debug("SSE client disconnected: {}", ex.getMessage());
}
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleUnexpected(Exception ex) {
log.error("unexpected error", ex);