Resilience4j: Error response returned by the server is ignored by resilience4j

Created on 14 Aug 2019  路  6Comments  路  Source: resilience4j/resilience4j

Hi

I am using the resilience4j with Feign client for communication with another server (lets say it is running on localhost:8090 with 1 exposed endpoint i.e. /sample). I am testing a case when I want to record only specific exceptions from the underlying http client library. So following is my config:

resilience4j.circuitbreaker:
  configs:
    default:
      registerHealthIndicator: true
      ringBufferSizeInClosedState: 4
      ringBufferSizeInHalfOpenState: 2
      automaticTransitionFromOpenToHalfOpenEnabled: true
      waitDurationInOpenState: 20s
      failureRateThreshold: 50
      eventConsumerBufferSize: 10
      ignoreExceptions:
        - com.resilience4j.exception.BusinessException
      recordExceptions:
        - java.net.SocketTimeoutException
        - feign.RetryableException

Now when the /sample endpoint returns a response with http status 400, which is a valid case and due to incorrect data passed. The /sample endpoint returns the following response if called separately

{
    "message": "this is a bad request"
}

But the resilience4j library ignores this response and returns the following response:

{
    "timestamp": "2019-08-14T09:40:00.568+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "status 400 reading MyFeignClient#feignMessage()",
    "path": "/resilience4j/feignClient"
}

How can I preserve the original response returned by the other server?

question

Most helpful comment

recordExceptions: Configures a list of classes that are recorded as a failure and thus increase the failure rate. Any exception matching or inheriting from one of the list should count as a failure, unless ignored via ignoreExceptions.
All other exceptions are not recorded, which means that they are ignored and thus do not count as success nor failure. If you add an exception to recordExceptions it's like: ignore all exceptions except this one.
If you add an exception to ignoreExceptions it's like: record all exceptions except this one.

The combination of ignoreExceptions and recordExceptions is helpful when you want to handle inheritance.
For example:
ignoreExceptions(Exception.class) and recordExceptions(Throwable.class) would record java.lang.Error as a failure.

All 6 comments

The CircuitBreaker only reacts on exceptions. If Feign throws an exception when the server returns a 400, the exceptions is recorded, unless you ignore it. But it's the duty of your code to catch the exception and return something useful.
Does your application act as a proxy and must forward the original message to the client?

We are into microservice architecture and some of our services are a proxy and some others show their own message. So we do want to retain the error messages returned by other services to show the actual message to the very first caller i.e from where the request started originally.

Resilience4j does not prevent you from doing it. I think you just have to look at Feign error handling.

Ok thanks for help. Also, can you explain how the ignoreExceptions and recordExceptions works together. Can you validate my following understanding and respond if they are correct or incorrect:

  1. ignoreExceptions: It will ignore only those exceptions which are listed against this property. All the other exceptions (along with the ones mentioned in recordExceptions) will be recorded and count as a failure in the ring buffer.

  2. recordExceptions: It will record only those exceptions which are listed against this property. All the other exceptions (along with the ones mentioned in ignoreExceptions) will be not be recorded and will be counted as success in the ring buffer.

recordExceptions: Configures a list of classes that are recorded as a failure and thus increase the failure rate. Any exception matching or inheriting from one of the list should count as a failure, unless ignored via ignoreExceptions.
All other exceptions are not recorded, which means that they are ignored and thus do not count as success nor failure. If you add an exception to recordExceptions it's like: ignore all exceptions except this one.
If you add an exception to ignoreExceptions it's like: record all exceptions except this one.

The combination of ignoreExceptions and recordExceptions is helpful when you want to handle inheritance.
For example:
ignoreExceptions(Exception.class) and recordExceptions(Throwable.class) would record java.lang.Error as a failure.

Closed in favor of #568

Was this page helpful?
0 / 5 - 0 ratings