diff --git a/CHANGES.md b/CHANGES.md
index 1f5d7de1..6d663579 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -1,3 +1,6 @@
+### Version 3.0
+* decoupled ErrorDecoder from fallback handling
+
### Version 2.0.0
* removes guava and jax-rs dependencies
* adds JAX-RS integration
diff --git a/feign-core/src/main/java/feign/MethodHandler.java b/feign-core/src/main/java/feign/MethodHandler.java
index 149addf9..7f6d9327 100644
--- a/feign-core/src/main/java/feign/MethodHandler.java
+++ b/feign-core/src/main/java/feign/MethodHandler.java
@@ -111,7 +111,7 @@ final class MethodHandler {
}
return decoder.decode(configKey, response, returnType);
} else {
- return errorDecoder.decode(configKey, response, returnType);
+ throw errorDecoder.decode(configKey, response);
}
} catch (Throwable e) {
ensureBodyClosed(response);
diff --git a/feign-core/src/main/java/feign/codec/ErrorDecoder.java b/feign-core/src/main/java/feign/codec/ErrorDecoder.java
index 08a75faa..16993504 100644
--- a/feign-core/src/main/java/feign/codec/ErrorDecoder.java
+++ b/feign-core/src/main/java/feign/codec/ErrorDecoder.java
@@ -15,7 +15,6 @@
*/
package feign.codec;
-import java.lang.reflect.Type;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -35,9 +34,7 @@ import static java.util.concurrent.TimeUnit.NANOSECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
/**
- * Allows you to massage an exception into a application-specific one, or
- * fallback to a default value. Falling back to null on
- * {@link Response#status() status 404}, or converting out to a throttle
+ * Allows you to massage an exception into a application-specific one. Converting out to a throttle
* exception are examples of this in use.
*
* Ex.
@@ -45,12 +42,12 @@ import static java.util.concurrent.TimeUnit.SECONDS;
*
* class IllegalArgumentExceptionOn404Decoder extends ErrorDecoder { * - * @Override - * public Object decode(String methodKey, Response response, Type<?> type) throws Throwable { + * @Override + * public Exception decode(String methodKey, Response response) { * if (response.status() == 404) * throw new IllegalArgumentException("zone not found"); - * return ErrorDecoder.DEFAULT.decode(request, response, type); - * } + * return ErrorDecoder.DEFAULT.decode(methodKey, request, response); + * } * * } *@@ -59,33 +56,29 @@ public interface ErrorDecoder { /** * Implement this method in order to decode an HTTP {@link Response} when - * {@link Response#status()} is not in the 2xx range. Please raise - * application-specific exceptions or return fallback values where possible. - * If your exception is retryable, wrap or subclass - * {@link RetryableException} + * {@link Response#status()} is not in the 2xx range. Please raise application-specific exceptions where possible. + * If your exception is retryable, wrap or subclass {@link RetryableException} * * @param methodKey {@link feign.Feign#configKey} of the java method that invoked the request. ex. {@code IAM#getUser()} * @param response HTTP response where {@link Response#status() status} is greater than or equal to {@code 300}. - * @param type Target object type. - * @return instance of {@code type} - * @throws Throwable IOException, if there was a network error reading the - * response or an application-specific exception decoded by the - * implementation. If the throwable is retryable, it should be - * wrapped, or a subtype of {@link RetryableException} + * @return Exception IOException, if there was a network error reading the + * response or an application-specific exception decoded by the + * implementation. If the throwable is retryable, it should be + * wrapped, or a subtype of {@link RetryableException} */ - public Object decode(String methodKey, Response response, Type type) throws Throwable; + public Exception decode(String methodKey, Response response); public static final ErrorDecoder DEFAULT = new ErrorDecoder() { private final RetryAfterDecoder retryAfterDecoder = new RetryAfterDecoder(); @Override - public Object decode(String methodKey, Response response, Type type) throws Throwable { + public Exception decode(String methodKey, Response response) { FeignException exception = errorStatus(methodKey, response); Date retryAfter = retryAfterDecoder.apply(firstOrNull(response.headers(), RETRY_AFTER)); if (retryAfter != null) - throw new RetryableException(exception.getMessage(), exception, retryAfter); - throw exception; + return new RetryableException(exception.getMessage(), exception, retryAfter); + return exception; } private