Exception Handling
About
In microservices or any distributed systems, remote API calls are inherently unreliable due to:
Network latency or timeouts
API version mismatches
Temporary service outages
Unauthorized or invalid requests
Resource not found (e.g., user doesn’t exist)
Instead of letting these issues break our application flow, proper exception handling helps us:
Provide informative responses to clients
Avoid cascading failures
Enable automated fallbacks
Log and trace failures for observability
Enforce clean separation of concerns between service call logic and failure behavior
How OpenFeign Handles Exceptions ?
OpenFeign does not throw HttpClientErrorException or HttpServerErrorException like RestTemplate. Instead:
It throws
FeignException, a base class for all client errors.Subtypes like
FeignException.NotFound,FeignException.BadRequestrepresent specific HTTP statuses.The exception encapsulates the raw response, status code, and response body which we can inspect or log.
1. Client-Side I/O Exceptions (Request-Time Errors)
These exceptions happen before the HTTP request even reaches the server. They usually indicate a problem in the request pipeline itself, such as:
Network unreachable (e.g., DNS resolution fails, host unreachable)
Timeout while establishing a connection
TLS handshake failure
Serialization error while preparing the request body
Connection reset by peer
These are different from typical HTTP response errors (like 404 or 500), because no HTTP response is returned.
How Does OpenFeign Represent These ?
When such exceptions occur:
OpenFeign throws
FeignExceptionor wraps lower-level exceptions (e.g.,IOException,SocketTimeoutException) asRetryableExceptionor rawRuntimeException.
In Spring Cloud OpenFeign, we can intercept these exceptions in:
A global
@ControllerAdviceA custom Feign
ErrorDecoderif Feign tries to wrap itA fallback method if configured
Example: Handling I/O Failures in a Safe Way
Let’s say a downstream service is unavailable, and the client fails at request time.
Feign Client Definition
Fallback Implementation
This will catch I/O-level failures and prevent the caller from crashing.
Catching Low-Level Exceptions (Manually)
If we want full control and don’t use a fallback, catch FeignException or nested IOException:
Better: Custom ErrorDecoder with Logging
Even request-time failures can be caught in a custom decoder:
Detecting Request-Time vs Response-Time Failures
To detect request-time I/O errors, we can configure Feign to use a Retryer or add a custom interceptor and logger.
2. Server Response Exceptions (Non-2xx Responses)
These occur when the request successfully reaches the server, but the server returns a non-2xx HTTP status code, such as:
404 Not Found400 Bad Request401 Unauthorized500 Internal Server Error
These aren't client-side I/O errors they represent a valid HTTP response indicating server-side rejection or failure.
How OpenFeign Handles Them ?
OpenFeign by default throws a FeignException (a subclass of RuntimeException) when the server returns a non-successful HTTP status.
We can handle these exceptions by:
Catching
FeignExceptionin our business codeDefining a custom
ErrorDecoderUsing fallbacks with
@FeignClient(fallback = …)
Exception Type Mapping in Feign
4xx
FeignException.ClientError
5xx
FeignException.ServerError
Other
FeignException
Example: Basic Feign Client
Feign Client Interface
Calling the Client and Handling Server Errors
Custom ErrorDecoder to Handle Server Responses Gracefully
Instead of handling exceptions everywhere, define a central place to decode them.
Fallback Option: Safe Fallback for Errors
3. Deserialization and Response Mapping Errors
Deserialization errors occur after a successful HTTP response (i.e., a 2xx status), but when Feign tries to convert the JSON/XML body into a Java object (POJO) and fails.
These are runtime exceptions and common reasons include:
Mismatched or missing fields in the POJO
Incorrect data types (e.g., expecting
intbut receiving a string)Invalid or unexpected response structure
Jackson misconfiguration
How Feign Handles Deserialization ?
Feign uses Jackson (via Spring Cloud OpenFeign) by default to deserialize the HTTP response into a Java object. If deserialization fails, it throws:
or
These typically bubble up as:
Example Scenario
Feign Client
Account POJO (Incorrect)
JSON Response
Here, deserialization will fail because Jackson looks for userName, but the JSON has username.
How to Fix / Prevent
1. Match Field Names Exactly
Use @JsonProperty if field names differ.
2. Enable Logging for Debugging
Catching Deserialization Errors Globally
Wrap our call in a try-catch and catch mapping exceptions:
Note: Jackson exceptions might get wrapped inside Feign or not be thrown directly, so sometimes using a fallback or decoding error body helps.
Using a Custom Decoder
Override Jackson decoder for finer control:
Last updated