Feign exception handling in Spring Cloud

Upasana | December 10, 2019 | 2 min read | 14,648 views


Feign is a declarative web service client for inter-service communicate. It is quite similar to retrofit that is used as a web service client in android.

Feign

Feign is a Java to HTTP client binder inspired by Retrofit, JAXRS-2.0, and WebSocket. Feign’s first goal was reducing the complexity of binding Denominator uniformly to HTTP APIs regardless of RESTfulness.

Exception handling with Feign

OpenFeign’s FeignException doesn’t bind to a specific HTTP status (i.e. doesn’t use Spring’s @ResponseStatus annotation), which makes Spring default to 500 whenever faced with a FeignException.

Sample response when FeignException occurs
{
    "timestamp": "2019-07-28T08:53:12.168+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "status 400 reading client#sendMessage(MessagePayload)",
    "path": "/send-notification"
}

That’s because the root cause for FeignException may not be even related to Http status code sent by remote web service.

In order to propagate the actual error message to the client, we can write our custom ExceptionHandler using a ControllerAdvice.

FeignExceptionHandler.java
import feign.FeignException;
import org.json.JSONObject;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.Map;

@RestControllerAdvice
public class FeignExceptionHandler {

    @ExceptionHandler(FeignException.BadRequest.class)  (1)
    public Map<String, Object> handleFeignStatusException(FeignException e, HttpServletResponse response) {
        response.setStatus(e.status());
        return new JSONObject(e.contentUTF8()).toMap(); (2)
    }

}
1 Handling FeignException for BadRequests only. We can write similar ExceptionHandlers for other types of exceptions.
2 We are assuming here that remote web service returns a JSON response for error messages

After we add this ExceptionHandler, we will be able to see custom exception response with additional details from remote web service.

Propagating actual error message to the caller from remote web service
{
    "exception": "org.springframework.web.bind.MethodArgumentNotValidException",
    "path": "/api/message/notification/",
    "error_code": 2151,
    "message": "Target id not valid",
    "status": 400,
    "timestamp": 1564304731547
}

Top articles in this category:
  1. Feign RequestInterceptor in Spring Boot
  2. Feign Client Logging and connection timeout
  3. Java AWS Lambda using Spring Cloud Function
  4. AWS Lambda in Kotlin using Spring Cloud Function
  5. Retrofit vs Feign for Server Side
  6. Spring Boot Sidecar
  7. Prevent Lost Updates in Database Transaction using Spring Hibernate

Recommended books for interview preparation:

Find more on this topic: