diff --git a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java index b0562373f..0062611e2 100644 --- a/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java +++ b/processor/src/main/java/org/mapstruct/ap/internal/model/BeanMappingMethod.java @@ -296,8 +296,18 @@ public class BeanMappingMethod extends NormalTypeMappingMethod { existingVariableNames ); - if (factoryMethod != null && method instanceof ForgedMethod ) { - ( (ForgedMethod) method ).addThrownTypes( factoryMethod.getThrownTypes() ); + if ( method instanceof ForgedMethod ) { + ForgedMethod forgedMethod = (ForgedMethod) method; + if ( factoryMethod != null ) { + forgedMethod.addThrownTypes( factoryMethod.getThrownTypes() ); + } + + for ( PropertyMapping propertyMapping : propertyMappings ) { + if ( propertyMapping.getAssignment() != null ) { + forgedMethod.addThrownTypes( propertyMapping.getAssignment().getThrownTypes() ); + } + } + } MethodReference finalizeMethod = null; diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/Issue2174Test.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/Issue2174Test.java new file mode 100644 index 000000000..89359957c --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/Issue2174Test.java @@ -0,0 +1,45 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2174; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mapstruct.ap.testutil.IssueKey; +import org.mapstruct.ap.testutil.WithClasses; +import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; + +/** + * @author Filip Hrisafov + */ +@IssueKey("2174") +@RunWith(AnnotationProcessorTestRunner.class) +@WithClasses(UserMapper.class) +public class Issue2174Test { + + @Test + public void shouldNotWrapCheckedException() throws Exception { + + UserMapper.User user = UserMapper.INSTANCE.map( new UserMapper.UserDto( "Test City", "10000" ) ); + + assertThat( user ).isNotNull(); + assertThat( user.getAddress() ).isNotNull(); + assertThat( user.getAddress().getCity() ).isNotNull(); + assertThat( user.getAddress().getCity().getName() ).isEqualTo( "Test City" ); + assertThat( user.getAddress().getCode() ).isNotNull(); + assertThat( user.getAddress().getCode().getCode() ).isEqualTo( "10000" ); + + assertThatThrownBy( () -> UserMapper.INSTANCE.map( new UserMapper.UserDto( "Zurich", "10000" ) ) ) + .isInstanceOf( UserMapper.CityNotFoundException.class ) + .hasMessage( "City with name 'Zurich' does not exist" ); + + assertThatThrownBy( () -> UserMapper.INSTANCE.map( new UserMapper.UserDto( "Test City", "1000" ) ) ) + .isInstanceOf( UserMapper.PostalCodeNotFoundException.class ) + .hasMessage( "Postal code '1000' does not exist" ); + } +} diff --git a/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/UserMapper.java b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/UserMapper.java new file mode 100644 index 000000000..025201b30 --- /dev/null +++ b/processor/src/test/java/org/mapstruct/ap/test/bugs/_2174/UserMapper.java @@ -0,0 +1,128 @@ +/* + * Copyright MapStruct Authors. + * + * Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0 + */ +package org.mapstruct.ap.test.bugs._2174; + +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; +import org.mapstruct.factory.Mappers; + +/** + * @author Filip Hrisafov + */ +@Mapper +public interface UserMapper { + + UserMapper INSTANCE = Mappers.getMapper( UserMapper.class ); + + @Mapping(target = "address.city", source = "city") + @Mapping(target = "address.code", source = "postalCode") + User map(UserDto dto) throws CityNotFoundException, PostalCodeNotFoundException; + + default City mapCity(String city) throws CityNotFoundException { + if ( "Test City".equals( city ) ) { + return new City( city ); + } + + throw new CityNotFoundException( "City with name '" + city + "' does not exist" ); + } + + default PostalCode mapCode(String code) throws PostalCodeNotFoundException { + if ( "10000".equals( code ) ) { + return new PostalCode( code ); + } + + throw new PostalCodeNotFoundException( "Postal code '" + code + "' does not exist" ); + } + + class UserDto { + private final String city; + private final String postalCode; + + public UserDto(String city, String postalCode) { + this.city = city; + this.postalCode = postalCode; + } + + public String getCity() { + return city; + } + + public String getPostalCode() { + return postalCode; + } + } + + class User { + + private final Address address; + + public User(Address address) { + this.address = address; + } + + public Address getAddress() { + return address; + } + } + + class Address { + private final City city; + private final PostalCode code; + + public Address(City city, PostalCode code) { + this.city = city; + this.code = code; + } + + public City getCity() { + return city; + } + + public PostalCode getCode() { + return code; + } + } + + class City { + + private final String name; + + public City(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + class PostalCode { + + private final String code; + + public PostalCode(String code) { + this.code = code; + } + + public String getCode() { + return code; + } + } + + class CityNotFoundException extends Exception { + + public CityNotFoundException(String message) { + super( message ); + } + } + + class PostalCodeNotFoundException extends Exception { + + public PostalCodeNotFoundException(String message) { + super( message ); + } + } +}