Skip to content

Commit 0e28e24

Browse files
committed
Rethrow ConverterNotFoundException when possible
Update `BindConverter` to throw the first `ConversionFailedException` rather than always throwing `ConverterNotFoundException`. See gh-27028
1 parent 9415678 commit 0e28e24

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

spring-boot-project/spring-boot/src/main/java/org/springframework/boot/context/properties/bind/BindConverter.java

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -34,7 +34,9 @@
3434
import org.springframework.boot.convert.ApplicationConversionService;
3535
import org.springframework.core.ResolvableType;
3636
import org.springframework.core.convert.ConversionException;
37+
import org.springframework.core.convert.ConversionFailedException;
3738
import org.springframework.core.convert.ConversionService;
39+
import org.springframework.core.convert.ConverterNotFoundException;
3840
import org.springframework.core.convert.TypeDescriptor;
3941
import org.springframework.core.convert.converter.ConditionalGenericConverter;
4042
import org.springframework.core.convert.support.GenericConversionService;
@@ -157,17 +159,20 @@ public <T> T convert(Object source, Class<T> targetType) {
157159

158160
@Override
159161
public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {
160-
for (int i = 0; i < this.delegates.size() - 1; i++) {
162+
ConversionException failure = null;
163+
for (ConversionService delegate : this.delegates) {
161164
try {
162-
ConversionService delegate = this.delegates.get(i);
163165
if (delegate.canConvert(sourceType, targetType)) {
164166
return delegate.convert(source, sourceType, targetType);
165167
}
166168
}
167169
catch (ConversionException ex) {
170+
if (failure == null && ex instanceof ConversionFailedException) {
171+
failure = ex;
172+
}
168173
}
169174
}
170-
return this.delegates.get(this.delegates.size() - 1).convert(source, sourceType, targetType);
175+
throw (failure != null) ? failure : new ConverterNotFoundException(sourceType, targetType);
171176
}
172177

173178
}

spring-boot-project/spring-boot/src/test/java/org/springframework/boot/context/properties/bind/BindConverterTests.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2020 the original author or authors.
2+
* Copyright 2012-2021 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -30,6 +30,7 @@
3030
import org.springframework.beans.PropertyEditorRegistry;
3131
import org.springframework.boot.convert.ApplicationConversionService;
3232
import org.springframework.core.ResolvableType;
33+
import org.springframework.core.convert.ConversionFailedException;
3334
import org.springframework.core.convert.ConversionService;
3435
import org.springframework.core.convert.ConverterNotFoundException;
3536
import org.springframework.core.convert.TypeDescriptor;
@@ -183,6 +184,14 @@ void fallsBackToApplicationConversionService() {
183184
assertThat(result.getSeconds()).isEqualTo(10);
184185
}
185186

187+
@Test // gh-27028
188+
void convertWhenConversionFailsThrowsConversionFailedExceptionRatherThanConverterNotFoundException() {
189+
BindConverter bindConverter = BindConverter.get(ApplicationConversionService.getSharedInstance(), null);
190+
assertThatExceptionOfType(ConversionFailedException.class)
191+
.isThrownBy(() -> bindConverter.convert("com.example.Missing", ResolvableType.forClass(Class.class)))
192+
.withRootCauseInstanceOf(ClassNotFoundException.class);
193+
}
194+
186195
private BindConverter getPropertyEditorOnlyBindConverter(
187196
Consumer<PropertyEditorRegistry> propertyEditorInitializer) {
188197
return BindConverter.get(new ThrowingConversionService(), propertyEditorInitializer);

0 commit comments

Comments
 (0)