From 98a925eb0200be0345aad8d167a4a730d122e97f Mon Sep 17 00:00:00 2001 From: Marvin Froeder Date: Tue, 22 Jan 2019 13:43:19 +1300 Subject: [PATCH] Make status mandatory --- core/src/main/java/feign/FeignException.java | 15 ++++++++++----- core/src/main/java/feign/RetryableException.java | 10 +++++----- .../main/java/feign/SynchronousMethodHandler.java | 4 ++-- .../main/java/feign/codec/DecodeException.java | 10 +++++----- .../main/java/feign/codec/EncodeException.java | 8 ++++---- core/src/main/java/feign/codec/ErrorDecoder.java | 5 +++-- core/src/main/java/feign/codec/StringDecoder.java | 5 +++-- core/src/test/java/feign/FeignTest.java | 8 ++++---- core/src/test/java/feign/RetryerTest.java | 10 +++++----- .../feign/jackson/JacksonIteratorDecoder.java | 6 +++--- jaxb/src/main/java/feign/jaxb/JAXBDecoder.java | 8 ++++---- sax/src/main/java/feign/sax/SAXDecoder.java | 6 +++--- soap/src/main/java/feign/soap/SOAPDecoder.java | 10 +++++----- 13 files changed, 56 insertions(+), 49 deletions(-) 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();