Merge branch 'fix/response-status-exception-preserve-code' into 'main'
fix(rest-api): preserve status code from ResponseStatusException See merge request 2-6/2-6-4/terravault/ordinis!211
This commit is contained in:
+28
@@ -11,6 +11,7 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||
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.NoHandlerFoundException;
|
||||
import org.springframework.web.servlet.resource.NoResourceFoundException;
|
||||
|
||||
@@ -112,6 +113,33 @@ public class GlobalExceptionHandler {
|
||||
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Preserve status code from {@link ResponseStatusException} (Spring's standard
|
||||
* way чтобы throw a specific HTTP status from controller). Without explicit
|
||||
* handler the generic fallback below catches it и turns 401/403/409 в 500 —
|
||||
* каждый use of throw new ResponseStatusException(...) silently downgraded.
|
||||
*
|
||||
* <p>Observed bug: MeNotificationsPreferencesController.requireSub() throws
|
||||
* 401 anonymous, но клиент получал 500 пока этот handler не появился.
|
||||
*/
|
||||
@ExceptionHandler(ResponseStatusException.class)
|
||||
public ResponseEntity<ApiErrorResponse> onResponseStatusException(ResponseStatusException e) {
|
||||
int status = e.getStatusCode().value();
|
||||
String reason = e.getReason() != null ? e.getReason() : e.getStatusCode().toString();
|
||||
// Lower-case-snake_case code from status reason — best-effort, falls back
|
||||
// на 'http_<NNN>' если reason missing/multi-word.
|
||||
String code = (e.getReason() != null && !e.getReason().contains(" "))
|
||||
? e.getReason().toLowerCase().replace(' ', '_')
|
||||
: "http_" + status;
|
||||
if (status >= 500) {
|
||||
log.error("ResponseStatusException 5xx: {}", reason, e);
|
||||
} else {
|
||||
log.debug("ResponseStatusException {}: {}", status, reason);
|
||||
}
|
||||
var body = ApiErrorResponse.of(status, code, reason, currentTraceId());
|
||||
return ResponseEntity.status(e.getStatusCode()).body(body);
|
||||
}
|
||||
|
||||
@ExceptionHandler(Exception.class)
|
||||
public ResponseEntity<ApiErrorResponse> onGeneric(Exception e) {
|
||||
log.error("Unhandled exception in REST API", e);
|
||||
|
||||
Reference in New Issue
Block a user