From 4847ee80b0450f6328d319f9dc853dbda8258b3a Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Tue, 25 Nov 2025 19:03:08 +0000 Subject: [PATCH] Add required type to TypeMismatchException message args Closes gh-35837 --- .../ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc | 2 +- .../method/annotation/ResponseEntityExceptionHandler.java | 5 +++-- .../annotation/ResponseEntityExceptionHandlerTests.java | 4 ++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc index ce39fbfca07..6fb85ed96f4 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-ann-rest-exceptions.adoc @@ -175,7 +175,7 @@ Message codes and arguments for each error are also resolved via `MessageSource` | `TypeMismatchException` | (default) -| `+{0}+` property name, `+{1}+` property value +| `+{0}+` property name, `+{1}+` property value, `+{2}+` simple name of required type | `UnsatisfiedServletRequestParameterException` | (default) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java index 2b77e177b4e..9cb5a30e8bb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandler.java @@ -466,7 +466,7 @@ public abstract class ResponseEntityExceptionHandler implements MessageSourceAwa /** * Customize the handling of {@link TypeMismatchException}. - *

By default this method creates a {@link ProblemDetail} with the status + *

By default, this method creates a {@link ProblemDetail} with the status * and a short detail message, and also looks up an override for the detail * via {@link MessageSource}, before delegating to * {@link #handleExceptionInternal}. @@ -480,7 +480,8 @@ public abstract class ResponseEntityExceptionHandler implements MessageSourceAwa protected @Nullable ResponseEntity handleTypeMismatch( TypeMismatchException ex, HttpHeaders headers, HttpStatusCode status, WebRequest request) { - Object[] args = {ex.getPropertyName(), ex.getValue()}; + Object[] args = {ex.getPropertyName(), ex.getValue(), + (ex.getRequiredType() != null ? ex.getRequiredType().getSimpleName() : "")}; String defaultDetail = "Failed to convert '" + args[0] + "' with value: '" + args[1] + "'"; String messageCode = ErrorResponse.getDefaultDetailMessageCode(TypeMismatchException.class, null); ProblemDetail body = createProblemDetail(ex, status, defaultDetail, messageCode, args, request); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java index e3a310e5b79..1282eccaa51 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/mvc/method/annotation/ResponseEntityExceptionHandlerTests.java @@ -245,7 +245,7 @@ class ResponseEntityExceptionHandlerTests { StaticMessageSource messageSource = new StaticMessageSource(); messageSource.addMessage( ErrorResponse.getDefaultDetailMessageCode(TypeMismatchException.class, null), locale, - "Failed to set {0} to value: {1}"); + "Failed to set {0} to value: {1} for type {2}"); this.exceptionHandler.setMessageSource(messageSource); @@ -253,7 +253,7 @@ class ResponseEntityExceptionHandlerTests { new TypeMismatchException(new PropertyChangeEvent(this, "name", "John", "James"), String.class)); ProblemDetail body = (ProblemDetail) entity.getBody(); - assertThat(body.getDetail()).isEqualTo("Failed to set name to value: James"); + assertThat(body.getDetail()).isEqualTo("Failed to set name to value: James for type String"); } finally { LocaleContextHolder.resetLocaleContext();