diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactoryBean.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactoryBean.java index 345a6bba..7b4791a9 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactoryBean.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientFactoryBean.java @@ -21,6 +21,7 @@ import java.util.Objects; import feign.Client; import feign.Contract; +import feign.ExceptionPropagationPolicy; import feign.Feign; import feign.Logger; import feign.QueryMapEncoder; @@ -156,6 +157,11 @@ class FeignClientFactoryBean if (this.decode404) { builder.decode404(); } + ExceptionPropagationPolicy exceptionPropagationPolicy = getOptional(context, + ExceptionPropagationPolicy.class); + if (exceptionPropagationPolicy != null) { + builder.exceptionPropagationPolicy(exceptionPropagationPolicy); + } } protected void configureUsingProperties( @@ -210,6 +216,10 @@ class FeignClientFactoryBean if (Objects.nonNull(config.getContract())) { builder.contract(getOrInstantiate(config.getContract())); } + + if (Objects.nonNull(config.getExceptionPropagationPolicy())) { + builder.exceptionPropagationPolicy(config.getExceptionPropagationPolicy()); + } } private T getOrInstantiate(Class tClass) { diff --git a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientProperties.java b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientProperties.java index f8dd51a4..0977adeb 100644 --- a/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientProperties.java +++ b/spring-cloud-openfeign-core/src/main/java/org/springframework/cloud/openfeign/FeignClientProperties.java @@ -22,6 +22,7 @@ import java.util.Map; import java.util.Objects; import feign.Contract; +import feign.ExceptionPropagationPolicy; import feign.Logger; import feign.RequestInterceptor; import feign.Retryer; @@ -111,6 +112,8 @@ public class FeignClientProperties { private Class contract; + private ExceptionPropagationPolicy exceptionPropagationPolicy; + public Logger.Level getLoggerLevel() { return this.loggerLevel; } @@ -192,6 +195,15 @@ public class FeignClientProperties { this.contract = contract; } + public ExceptionPropagationPolicy getExceptionPropagationPolicy() { + return exceptionPropagationPolicy; + } + + public void setExceptionPropagationPolicy( + ExceptionPropagationPolicy exceptionPropagationPolicy) { + this.exceptionPropagationPolicy = exceptionPropagationPolicy; + } + @Override public boolean equals(Object o) { if (this == o) { @@ -210,14 +222,17 @@ public class FeignClientProperties { && Objects.equals(this.decode404, that.decode404) && Objects.equals(this.encoder, that.encoder) && Objects.equals(this.decoder, that.decoder) - && Objects.equals(this.contract, that.contract); + && Objects.equals(this.contract, that.contract) + && Objects.equals(this.exceptionPropagationPolicy, + that.exceptionPropagationPolicy); } @Override public int hashCode() { return Objects.hash(this.loggerLevel, this.connectTimeout, this.readTimeout, this.retryer, this.errorDecoder, this.requestInterceptors, - this.decode404, this.encoder, this.decoder, this.contract); + this.decode404, this.encoder, this.decoder, this.contract, + this.exceptionPropagationPolicy); } } diff --git a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientOverrideDefaultsTests.java b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientOverrideDefaultsTests.java index fe21f2e4..87190c13 100644 --- a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientOverrideDefaultsTests.java +++ b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientOverrideDefaultsTests.java @@ -17,6 +17,7 @@ package org.springframework.cloud.openfeign; import feign.Contract; +import feign.ExceptionPropagationPolicy; import feign.Feign; import feign.Logger; import feign.QueryMapEncoder; @@ -151,6 +152,14 @@ public class FeignClientOverrideDefaultsTests { .isEqualTo(2); } + @Test + public void exceptionPropagationPolicy() { + assertThat(this.context.getInstances("foo", ExceptionPropagationPolicy.class)) + .isNull(); + assertThat(this.context.getInstances("bar", ExceptionPropagationPolicy.class)) + .containsValues(ExceptionPropagationPolicy.UNWRAP); + } + @FeignClient(name = "foo", url = "https://foo", configuration = FooConfiguration.class) interface FooClient { @@ -252,6 +261,11 @@ public class FeignClientOverrideDefaultsTests { return new BeanQueryMapEncoder(); } + @Bean + public ExceptionPropagationPolicy exceptionPropagationPolicy() { + return ExceptionPropagationPolicy.UNWRAP; + } + } } diff --git a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientUsingPropertiesTests.java b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientUsingPropertiesTests.java index 762e5b93..f2a5345b 100644 --- a/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientUsingPropertiesTests.java +++ b/spring-cloud-openfeign-core/src/test/java/org/springframework/cloud/openfeign/FeignClientUsingPropertiesTests.java @@ -16,7 +16,9 @@ package org.springframework.cloud.openfeign; +import java.io.IOException; import java.lang.reflect.Type; +import java.net.SocketTimeoutException; import java.util.Collections; import java.util.Map; @@ -78,6 +80,8 @@ public class FeignClientUsingPropertiesTests { private FeignClientFactoryBean barFactoryBean; + private FeignClientFactoryBean unwrapFactoryBean; + private FeignClientFactoryBean formFactoryBean; public FeignClientUsingPropertiesTests() { @@ -89,6 +93,10 @@ public class FeignClientUsingPropertiesTests { this.barFactoryBean.setContextId("bar"); this.barFactoryBean.setType(FeignClientFactoryBean.class); + this.unwrapFactoryBean = new FeignClientFactoryBean(); + this.unwrapFactoryBean.setContextId("unwrap"); + this.unwrapFactoryBean.setType(FeignClientFactoryBean.class); + this.formFactoryBean = new FeignClientFactoryBean(); this.formFactoryBean.setContextId("form"); this.formFactoryBean.setType(FeignClientFactoryBean.class); @@ -106,6 +114,12 @@ public class FeignClientUsingPropertiesTests { "http://localhost:" + this.port); } + public UnwrapClient unwrapClient() { + this.unwrapFactoryBean.setApplicationContext(this.applicationContext); + return this.unwrapFactoryBean.feign(this.context).target(UnwrapClient.class, + "http://localhost:" + this.port); + } + public FormClient formClient() { this.formFactoryBean.setApplicationContext(this.applicationContext); return this.formFactoryBean.feign(this.context).target(FormClient.class, @@ -124,6 +138,12 @@ public class FeignClientUsingPropertiesTests { fail("it should timeout"); } + @Test(expected = SocketTimeoutException.class) + public void testUnwrap() throws Exception { + unwrapClient().unwrap(); + fail("it should timeout"); + } + @Test public void testForm() { Map request = Collections.singletonMap("form", "Data"); @@ -145,6 +165,13 @@ public class FeignClientUsingPropertiesTests { } + protected interface UnwrapClient { + + @RequestMapping(method = RequestMethod.GET, value = "/bar") // intentionally /bar + String unwrap() throws IOException; + + } + protected interface FormClient { @RequestMapping(value = "/form", method = RequestMethod.POST, diff --git a/spring-cloud-openfeign-core/src/test/resources/feign-properties.properties b/spring-cloud-openfeign-core/src/test/resources/feign-properties.properties index b5b13c8f..0caec544 100644 --- a/spring-cloud-openfeign-core/src/test/resources/feign-properties.properties +++ b/spring-cloud-openfeign-core/src/test/resources/feign-properties.properties @@ -13,3 +13,6 @@ feign.client.config.foo.requestInterceptors[1]=org.springframework.cloud.openfei feign.client.config.bar.connectTimeout=1000 feign.client.config.bar.readTimeout=1000 feign.client.config.form.encoder=org.springframework.cloud.openfeign.FeignClientUsingPropertiesTests.FormEncoder +feign.client.config.unwrap.connectTimeout=1000 +feign.client.config.unwrap.readTimeout=1000 +feign.client.config.unwrap.exceptionPropagationPolicy=unwrap