mirror of
https://github.com/spring-projects/spring-framework.git
synced 2026-09-27 09:39:04 +00:00
ResponseStatusException should not override custom reason
Prior to this commit, `ResponseStatusException` would resolve the "detail" part of a problem detail response from message codes only (default or custom ones). If the `reason` given as an argument to the exception was a custom message, it would be overwritten in the process. This commit ensures that we use custom reason messages when they don't resolve as message codes. Fixes gh-36984
This commit is contained in:
+16
-11
@@ -17,6 +17,7 @@
|
||||
package org.springframework.web.server;
|
||||
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.jspecify.annotations.Nullable;
|
||||
|
||||
@@ -117,19 +118,23 @@ public class ResponseStatusException extends ErrorResponseException {
|
||||
|
||||
@Override
|
||||
public ProblemDetail updateAndGetBody(@Nullable MessageSource messageSource, Locale locale) {
|
||||
super.updateAndGetBody(messageSource, locale);
|
||||
|
||||
// The reason may be a code (consistent with ResponseStatusExceptionResolver)
|
||||
|
||||
if (messageSource != null && getReason() != null && getReason().equals(getBody().getDetail())) {
|
||||
Object[] arguments = getDetailMessageArguments(messageSource, locale);
|
||||
String resolved = messageSource.getMessage(getReason(), arguments, null, locale);
|
||||
if (resolved != null) {
|
||||
getBody().setDetail(resolved);
|
||||
String reason = getReason();
|
||||
if (reason != null) {
|
||||
boolean detailNotCustomized = reason.equals(getBody().getDetail());
|
||||
super.updateAndGetBody(messageSource, locale);
|
||||
if (!detailNotCustomized) {
|
||||
return getBody();
|
||||
}
|
||||
// The reason may itself be a code (consistent with ResponseStatusExceptionResolver)
|
||||
String resolved = null;
|
||||
if (messageSource != null) {
|
||||
resolved = messageSource.getMessage(reason, getDetailMessageArguments(messageSource, locale), null, locale);
|
||||
}
|
||||
// set to the custom reason if no message was resolved
|
||||
getBody().setDetail(Objects.requireNonNullElse(resolved, reason));
|
||||
return getBody();
|
||||
}
|
||||
|
||||
return getBody();
|
||||
return super.updateAndGetBody(messageSource, locale);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -424,6 +424,28 @@ class ErrorResponseExceptionTests {
|
||||
}
|
||||
}
|
||||
|
||||
@Test // gh-36984
|
||||
void responseStatusExceptionCustomReason() {
|
||||
Locale locale = Locale.UK;
|
||||
LocaleContextHolder.setLocale(locale);
|
||||
|
||||
try {
|
||||
String reason = "bad.request";
|
||||
String message = "Breaking Bad Request";
|
||||
StaticMessageSource messageSource = new StaticMessageSource();
|
||||
messageSource.addMessage(reason, locale, message);
|
||||
|
||||
String customReason = "my custom reason";
|
||||
ResponseStatusException ex = new ResponseStatusException(HttpStatus.BAD_REQUEST, customReason);
|
||||
|
||||
ProblemDetail problemDetail = ex.updateAndGetBody(messageSource, locale);
|
||||
assertThat(problemDetail.getDetail()).isEqualTo(customReason);
|
||||
}
|
||||
finally {
|
||||
LocaleContextHolder.resetLocaleContext();
|
||||
}
|
||||
}
|
||||
|
||||
private void assertStatus(ErrorResponse ex, HttpStatus status) {
|
||||
ProblemDetail body = ex.getBody();
|
||||
assertThat(ex.getStatusCode()).isEqualTo(status);
|
||||
|
||||
Reference in New Issue
Block a user