Browse Source
In Spring Boot 3.5, support was added for including the errors from a MethodValidationResult in the standard error response. It was requested in gh-42013 and implemented in gh-43330. With hindsight, the implementation went too far as it changed how all errors are serialized to JSON. This commit reworks the wrapping so that ObjectErrors are not wrapped, restoring Spring Boot 3.4's behavior. This is considered safe as the contents of an ObjectError are fairly limited and should serialize to JSON without problems. Other MessageSourceResolvable implementations are still wrapped as there are no limits on their contents and we cannot predict how suitable they are for JSON serialization. Closes gh-46260pull/46457/head
6 changed files with 127 additions and 15 deletions
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
/* |
||||
* Copyright 2012-present the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.boot.web.error; |
||||
|
||||
import java.util.List; |
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException; |
||||
import com.fasterxml.jackson.databind.ObjectMapper; |
||||
import org.junit.jupiter.api.Test; |
||||
|
||||
import org.springframework.context.MessageSourceResolvable; |
||||
import org.springframework.context.support.DefaultMessageSourceResolvable; |
||||
import org.springframework.validation.FieldError; |
||||
import org.springframework.validation.ObjectError; |
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat; |
||||
|
||||
/** |
||||
* Tests for {@link Error}. |
||||
* |
||||
* @author Andy Wilkinson |
||||
*/ |
||||
class ErrorTests { |
||||
|
||||
@Test |
||||
@SuppressWarnings({ "rawtypes", "removal" }) |
||||
@Deprecated(since = "3.5.4", forRemoval = true) |
||||
void wrapWrapsAllErrors() { |
||||
List<Error> wrapped = Error.wrap(List.of(new ObjectError("name", "message"), |
||||
new FieldError("name", "field", "message"), new CustomMessageSourceResolvable("code"))); |
||||
assertThat(wrapped).extracting((error) -> (Class) error.getClass()) |
||||
.containsExactly(Error.class, Error.class, Error.class); |
||||
} |
||||
|
||||
@Test |
||||
@SuppressWarnings("rawtypes") |
||||
void wrapIfNecessaryDoesNotWrapFieldErrorOrObjectError() { |
||||
List<MessageSourceResolvable> wrapped = Error.wrapIfNecessary(List.of(new ObjectError("name", "message"), |
||||
new FieldError("name", "field", "message"), new CustomMessageSourceResolvable("code"))); |
||||
assertThat(wrapped).extracting((error) -> (Class) error.getClass()) |
||||
.containsExactly(ObjectError.class, FieldError.class, Error.class); |
||||
} |
||||
|
||||
@Test |
||||
void errorCauseDoesNotAppearInJson() throws JsonProcessingException { |
||||
String json = new ObjectMapper() |
||||
.writeValueAsString(Error.wrapIfNecessary(List.of(new CustomMessageSourceResolvable("code")))); |
||||
assertThat(json).doesNotContain("some detail"); |
||||
} |
||||
|
||||
public static class CustomMessageSourceResolvable extends DefaultMessageSourceResolvable { |
||||
|
||||
CustomMessageSourceResolvable(String code) { |
||||
super(code); |
||||
} |
||||
|
||||
public String getDetail() { |
||||
return "some detail"; |
||||
} |
||||
|
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue