diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cd2a85a..78254ad6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +### Version 8.11 +* Adds HTTP status to FeignException for easier response handling + ### Version 8.10 * Reads class-level @Produces/@Consumes JAX-RS annotations * Supports POST without a body parameter diff --git a/core/src/main/java/feign/FeignException.java b/core/src/main/java/feign/FeignException.java index a85b9113..c24f8611 100644 --- a/core/src/main/java/feign/FeignException.java +++ b/core/src/main/java/feign/FeignException.java @@ -25,6 +25,7 @@ import static java.lang.String.format; public class FeignException extends RuntimeException { private static final long serialVersionUID = 0; + private int status; protected FeignException(String message, Throwable cause) { super(message, cause); @@ -34,6 +35,15 @@ public class FeignException extends RuntimeException { super(message); } + protected FeignException(int status, String message) { + super(message); + this.status = status; + } + + public int status() { + return this.status; + } + static FeignException errorReading(Request request, Response ignored, IOException cause) { return new FeignException( format("%s reading %s %s", cause.getMessage(), request.method(), request.url()), @@ -49,7 +59,7 @@ public class FeignException extends RuntimeException { } } catch (IOException ignored) { // NOPMD } - return new FeignException(message); + return new FeignException(response.status(), message); } static FeignException errorExecuting(Request request, IOException cause) { diff --git a/core/src/test/java/feign/codec/DefaultErrorDecoderTest.java b/core/src/test/java/feign/codec/DefaultErrorDecoderTest.java index bd49984e..a1d36b51 100644 --- a/core/src/test/java/feign/codec/DefaultErrorDecoderTest.java +++ b/core/src/test/java/feign/codec/DefaultErrorDecoderTest.java @@ -29,6 +29,7 @@ import feign.Response; import static feign.Util.RETRY_AFTER; import static feign.Util.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; public class DefaultErrorDecoderTest { @@ -54,13 +55,21 @@ public class DefaultErrorDecoderTest { thrown.expect(FeignException.class); thrown.expectMessage("status 500 reading Service#foo(); content:\nhello world"); - Response - response = - Response.create(500, "Internal server error", headers, "hello world", UTF_8); + Response response = Response.create(500, "Internal server error", headers, "hello world", UTF_8); throw errorDecoder.decode("Service#foo()", response); } + @Test + public void testFeignExceptionIncludesStatus() throws Throwable { + Response response = Response.create(400, "Bad request", headers, (byte[]) null); + + Exception exception = errorDecoder.decode("Service#foo()", response); + + assertThat(exception).isInstanceOf(FeignException.class); + assertThat(((FeignException) exception).status()).isEqualTo(400); + } + @Test public void retryAfterHeaderThrowsRetryableException() throws Throwable { thrown.expect(FeignException.class);