diff --git a/core/src/main/java/feign/FeignException.java b/core/src/main/java/feign/FeignException.java index f94d4d76a..7eef1b335 100644 --- a/core/src/main/java/feign/FeignException.java +++ b/core/src/main/java/feign/FeignException.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -26,17 +26,20 @@ public class FeignException extends RuntimeException { private int status; private byte[] content; - protected FeignException(String message, Throwable cause) { + protected FeignException(int status, String message, Throwable cause) { super(message, cause); + this.status = status; } - protected FeignException(String message, Throwable cause, byte[] content) { + protected FeignException(int status, String message, Throwable cause, byte[] content) { super(message, cause); + this.status = status; this.content = content; } - protected FeignException(String message) { + protected FeignException(int status, String message) { super(message); + this.status = status; } protected FeignException(int status, String message, byte[] content) { @@ -57,8 +60,9 @@ public String contentUTF8() { return new String(content, UTF_8); } - static FeignException errorReading(Request request, Response ignored, IOException cause) { + static FeignException errorReading(Request request, Response response, IOException cause) { return new FeignException( + response.status(), format("%s reading %s %s", cause.getMessage(), request.httpMethod(), request.url()), cause, request.body()); @@ -119,6 +123,7 @@ private static FeignException errorStatus(int status, String message, byte[] bod static FeignException errorExecuting(Request request, IOException cause) { return new RetryableException( + -1, format("%s executing %s %s", cause.getMessage(), request.httpMethod(), request.url()), request.httpMethod(), cause, diff --git a/core/src/main/java/feign/RetryableException.java b/core/src/main/java/feign/RetryableException.java index 8fd32c432..2aa3e8fed 100644 --- a/core/src/main/java/feign/RetryableException.java +++ b/core/src/main/java/feign/RetryableException.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -30,9 +30,9 @@ public class RetryableException extends FeignException { /** * @param retryAfter usually corresponds to the {@link feign.Util#RETRY_AFTER} header. */ - public RetryableException(String message, HttpMethod httpMethod, Throwable cause, + public RetryableException(int status, String message, HttpMethod httpMethod, Throwable cause, Date retryAfter) { - super(message, cause); + super(status, message, cause); this.httpMethod = httpMethod; this.retryAfter = retryAfter != null ? retryAfter.getTime() : null; } @@ -40,8 +40,8 @@ public RetryableException(String message, HttpMethod httpMethod, Throwable cause /** * @param retryAfter usually corresponds to the {@link feign.Util#RETRY_AFTER} header. */ - public RetryableException(String message, HttpMethod httpMethod, Date retryAfter) { - super(message); + public RetryableException(int status, String message, HttpMethod httpMethod, Date retryAfter) { + super(status, message); this.httpMethod = httpMethod; this.retryAfter = retryAfter != null ? retryAfter.getTime() : null; } diff --git a/core/src/main/java/feign/SynchronousMethodHandler.java b/core/src/main/java/feign/SynchronousMethodHandler.java index ef3c058bd..1dbd9d348 100644 --- a/core/src/main/java/feign/SynchronousMethodHandler.java +++ b/core/src/main/java/feign/SynchronousMethodHandler.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -177,7 +177,7 @@ Object decode(Response response) throws Throwable { } catch (FeignException e) { throw e; } catch (RuntimeException e) { - throw new DecodeException(e.getMessage(), e); + throw new DecodeException(response.status(), e.getMessage(), e); } } diff --git a/core/src/main/java/feign/codec/DecodeException.java b/core/src/main/java/feign/codec/DecodeException.java index 687a6ddfe..036914582 100644 --- a/core/src/main/java/feign/codec/DecodeException.java +++ b/core/src/main/java/feign/codec/DecodeException.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -28,15 +28,15 @@ public class DecodeException extends FeignException { /** * @param message the reason for the failure. */ - public DecodeException(String message) { - super(checkNotNull(message, "message")); + public DecodeException(int status, String message) { + super(status, checkNotNull(message, "message")); } /** * @param message possibly null reason for the failure. * @param cause the cause of the error. */ - public DecodeException(String message, Throwable cause) { - super(message, checkNotNull(cause, "cause")); + public DecodeException(int status, String message, Throwable cause) { + super(status, message, checkNotNull(cause, "cause")); } } diff --git a/core/src/main/java/feign/codec/EncodeException.java b/core/src/main/java/feign/codec/EncodeException.java index 517728366..57c586881 100644 --- a/core/src/main/java/feign/codec/EncodeException.java +++ b/core/src/main/java/feign/codec/EncodeException.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -13,8 +13,8 @@ */ package feign.codec; -import feign.FeignException; import static feign.Util.checkNotNull; +import feign.FeignException; /** * Similar to {@code javax.websocket.EncodeException}, raised when a problem occurs encoding a @@ -29,7 +29,7 @@ public class EncodeException extends FeignException { * @param message the reason for the failure. */ public EncodeException(String message) { - super(checkNotNull(message, "message")); + super(-1, checkNotNull(message, "message")); } /** @@ -37,6 +37,6 @@ public EncodeException(String message) { * @param cause the cause of the error. */ public EncodeException(String message, Throwable cause) { - super(message, checkNotNull(cause, "cause")); + super(-1, message, checkNotNull(cause, "cause")); } } diff --git a/core/src/main/java/feign/codec/ErrorDecoder.java b/core/src/main/java/feign/codec/ErrorDecoder.java index 2da7aefba..ab99aa396 100644 --- a/core/src/main/java/feign/codec/ErrorDecoder.java +++ b/core/src/main/java/feign/codec/ErrorDecoder.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -35,7 +35,7 @@ * *
* Ex: - * + * ** class IllegalArgumentExceptionOn404Decoder implements ErrorDecoder { * @@ -94,6 +94,7 @@ public Exception decode(String methodKey, Response response) { Date retryAfter = retryAfterDecoder.apply(firstOrNull(response.headers(), RETRY_AFTER)); if (retryAfter != null) { return new RetryableException( + response.status(), exception.getMessage(), response.request().httpMethod(), exception, diff --git a/core/src/main/java/feign/codec/StringDecoder.java b/core/src/main/java/feign/codec/StringDecoder.java index 16f2a6f17..2307a7c5b 100644 --- a/core/src/main/java/feign/codec/StringDecoder.java +++ b/core/src/main/java/feign/codec/StringDecoder.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -30,6 +30,7 @@ public Object decode(Response response, Type type) throws IOException { if (String.class.equals(type)) { return Util.toString(body.asReader()); } - throw new DecodeException(format("%s is not a type supported by this decoder.", type)); + throw new DecodeException(response.status(), + format("%s is not a type supported by this decoder.", type)); } } diff --git a/core/src/test/java/feign/FeignTest.java b/core/src/test/java/feign/FeignTest.java index 3f474312e..b8c678460 100644 --- a/core/src/test/java/feign/FeignTest.java +++ b/core/src/test/java/feign/FeignTest.java @@ -480,7 +480,7 @@ public void retryableExceptionInDecoder() throws Exception { public Object decode(Response response, Type type) throws IOException { String string = super.decode(response, type).toString(); if ("retry!".equals(string)) { - throw new RetryableException(string, HttpMethod.POST, null); + throw new RetryableException(response.status(), string, HttpMethod.POST, null); } return string; } @@ -540,7 +540,7 @@ public void ensureRetryerClonesItself() throws Exception { .errorDecoder(new ErrorDecoder() { @Override public Exception decode(String methodKey, Response response) { - return new RetryableException("play it again sam!", HttpMethod.POST, null); + return new RetryableException(response.status(), "play it again sam!", HttpMethod.POST, null); } }).target(TestInterface.class, "http://localhost:" + server.getPort()); @@ -564,7 +564,7 @@ public void throwsOriginalExceptionAfterFailedRetries() throws Exception { .errorDecoder(new ErrorDecoder() { @Override public Exception decode(String methodKey, Response response) { - return new RetryableException("play it again sam!", HttpMethod.POST, + return new RetryableException(response.status(), "play it again sam!", HttpMethod.POST, new TestInterfaceException(message), null); } }).target(TestInterface.class, "http://localhost:" + server.getPort()); @@ -587,7 +587,7 @@ public void throwsRetryableExceptionIfNoUnderlyingCause() throws Exception { .errorDecoder(new ErrorDecoder() { @Override public Exception decode(String methodKey, Response response) { - return new RetryableException(message, HttpMethod.POST, null); + return new RetryableException(response.status(), message, HttpMethod.POST, null); } }).target(TestInterface.class, "http://localhost:" + server.getPort()); diff --git a/core/src/test/java/feign/RetryerTest.java b/core/src/test/java/feign/RetryerTest.java index fcac120a4..ea8171105 100644 --- a/core/src/test/java/feign/RetryerTest.java +++ b/core/src/test/java/feign/RetryerTest.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -28,7 +28,7 @@ public class RetryerTest { @Test public void only5TriesAllowedAndExponentialBackoff() throws Exception { - RetryableException e = new RetryableException(null, null, null); + RetryableException e = new RetryableException(-1, null, null, null); Default retryer = new Retryer.Default(); assertEquals(1, retryer.attempt); assertEquals(0, retryer.sleptForMillis); @@ -61,14 +61,14 @@ protected long currentTimeMillis() { } }; - retryer.continueOrPropagate(new RetryableException(null, null, new Date(5000))); + retryer.continueOrPropagate(new RetryableException(-1, null, null, new Date(5000))); assertEquals(2, retryer.attempt); assertEquals(1000, retryer.sleptForMillis); } @Test(expected = RetryableException.class) public void neverRetryAlwaysPropagates() { - Retryer.NEVER_RETRY.continueOrPropagate(new RetryableException(null, null, new Date(5000))); + Retryer.NEVER_RETRY.continueOrPropagate(new RetryableException(-1, null, null, new Date(5000))); } @Test @@ -77,7 +77,7 @@ public void defaultRetryerFailsOnInterruptedException() { Thread.currentThread().interrupt(); RetryableException expected = - new RetryableException(null, null, new Date(System.currentTimeMillis() + 5000)); + new RetryableException(-1, null, null, new Date(System.currentTimeMillis() + 5000)); try { retryer.continueOrPropagate(expected); Thread.interrupted(); // reset interrupted flag in case it wasn't diff --git a/jackson/src/main/java/feign/jackson/JacksonIteratorDecoder.java b/jackson/src/main/java/feign/jackson/JacksonIteratorDecoder.java index 0ca3f2326..86d36d69f 100644 --- a/jackson/src/main/java/feign/jackson/JacksonIteratorDecoder.java +++ b/jackson/src/main/java/feign/jackson/JacksonIteratorDecoder.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -43,7 +43,7 @@ **
* Example:
- * + * *** Feign.builder() @@ -152,7 +152,7 @@ public boolean hasNext() { current = objectReader.readValue(parser); } catch (IOException e) { // Input Stream closed automatically by parser - throw new DecodeException(e.getMessage(), e); + throw new DecodeException(response.status(), e.getMessage(), e); } return current != null; } diff --git a/jaxb/src/main/java/feign/jaxb/JAXBDecoder.java b/jaxb/src/main/java/feign/jaxb/JAXBDecoder.java index 4485abcb6..158835f09 100644 --- a/jaxb/src/main/java/feign/jaxb/JAXBDecoder.java +++ b/jaxb/src/main/java/feign/jaxb/JAXBDecoder.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -32,13 +32,13 @@ *
* Basic example with with Feign.Builder: *
- * + * ** JAXBContextFactory jaxbFactory = new JAXBContextFactory.Builder() * .withMarshallerJAXBEncoding("UTF-8") * .withMarshallerSchemaLocation("http://apihost http://apihost/schema.xsd") * .build(); - * + * * api = Feign.builder() * .decoder(new JAXBDecoder(jaxbFactory)) * .target(MyApi.class, "http://api"); @@ -92,7 +92,7 @@ public Object decode(Response response, Type type) throws IOException { saxParserFactory.newSAXParser().getXMLReader(), new InputSource(response.body().asInputStream()))); } catch (JAXBException | ParserConfigurationException | SAXException e) { - throw new DecodeException(e.toString(), e); + throw new DecodeException(response.status(), e.toString(), e); } finally { if (response.body() != null) { response.body().close(); diff --git a/sax/src/main/java/feign/sax/SAXDecoder.java b/sax/src/main/java/feign/sax/SAXDecoder.java index 65acc60e2..02833e1a5 100644 --- a/sax/src/main/java/feign/sax/SAXDecoder.java +++ b/sax/src/main/java/feign/sax/SAXDecoder.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -37,7 +37,7 @@ * Decodes responses using SAX, which is supported both in normal JVM environments, as well Android. *
*Basic example with with Feign.Builder
- * + * ** api = Feign.builder() * .decoder(SAXDecoder.builder() @@ -87,7 +87,7 @@ public Object decode(Response response, Type type) throws IOException, DecodeExc } return handler.result(); } catch (SAXException e) { - throw new DecodeException(e.getMessage(), e); + throw new DecodeException(response.status(), e.getMessage(), e); } } diff --git a/soap/src/main/java/feign/soap/SOAPDecoder.java b/soap/src/main/java/feign/soap/SOAPDecoder.java index bfb19237e..29e789276 100644 --- a/soap/src/main/java/feign/soap/SOAPDecoder.java +++ b/soap/src/main/java/feign/soap/SOAPDecoder.java @@ -1,5 +1,5 @@ /** - * Copyright 2012-2018 The Feign Authors + * Copyright 2012-2019 The Feign Authors * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at @@ -44,14 +44,14 @@ ** * public interface MyApi { - * + * * @RequestLine("POST /getObject") * @Headers({ * "SOAPAction: getObject", * "Content-Type: text/xml" * }) * MyJaxbObjectResponse getObject(MyJaxbObjectRequest request); - * + * * } * * ... @@ -73,7 +73,7 @@ * log.info(faultException.getFault().getFaultString()); * } *- * + * * * * @see SOAPErrorDecoder @@ -123,7 +123,7 @@ public Object decode(Response response, Type type) throws IOException { .unmarshal(message.getSOAPBody().extractContentAsDocument()); } } catch (SOAPException | JAXBException e) { - throw new DecodeException(e.toString(), e); + throw new DecodeException(response.status(), e.toString(), e); } finally { if (response.body() != null) { response.body().close();