More details (URL, method, body preview) in FeignClient(Server)Exception message
See original GitHub issueCan we make the FeignException message look like:
409 Conflict during [POST] to [http://localhost:8080/endpoint], response: [{"error":{"code":409,"message":"You already own this bucket. Please select another name."}}]
instead of just:
status 409 reading FeignClient#getResponse()
Reason: Applications using Feign, communicate with multiple external systems.
As a developer, when I try to diagnose an issue in production, from the default exception message I cannot find out about:
- HTTP endpoint,
- HTTP method,
- the error response, which usually contains something interesting.
I think that the new format would improve developer experience. I would like to see the complete information from the moment when the issue occurred: which external system returned an error, what endpoint and response body was. Just like that.
This would automatically appear in the logs, so I do not need to 1st - search through the stacktraces to see which request that was, 2nd - try to reproduce the issue to see the actual response body. Especially hard with non-deterministic errors.
There are other ways to do it, but I think the exception message is most natural. Other ways I know, involve extra error handling code all around the application. And the new format would be almost no changes to users’ existing code base.
Actual (sample of current Feign logs):
feign.FeignException$Conflict: status 409 reading FeignClient#getResponse()
at feign.FeignException.clientErrorStatus(FeignException.java:118)
at feign.FeignException.errorStatus(FeignException.java:91)
at feign.FeignException.errorStatus(FeignException.java:86)
Expected (what the log entry could look like):
409 Conflict during [POST] to [http://localhost:8080/endpoint], response: [{"error":{"code":409,"message":"You already own this bucket. Please select another name."}}]
feign.FeignException$Conflict: 409 Conflict during [POST] to [http://localhost:8080/endpoint], response: [{"error":{"code":409,"message":"You already own this bucket. Please select another name."}}]
at feign.FeignException.clientErrorStatus(FeignException.java:118)
at feign.FeignException.errorStatus(FeignException.java:91)
at feign.FeignException.errorStatus(FeignException.java:86)
I have implemented this multiple times already, in multiple projects. I think Feign would be a better place to do that.
Note - back in Feign 10.0.1, the message contained the complete body of the response (any size, even 1MB worked), which might cause problems. But I think the response can be abbreviated to just first 100 - 500 characters of the body.
This is basically the same idea as here: https://github.com/spring-projects/spring-framework/pull/1956 . I can provide a pull request for this, if you like the general concept.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:2
- Comments:10 (10 by maintainers)
@jerzykrlk
The
ErrorDecoder
is the right component for users to add their own exception management, and it is possible to achieve everything in your proposal by implementing your ownErrorDecoder
. HoweverFeignException
does not provide enough context to support your needs. My suggestion is to start by adding that context toFeignException
and then consider how this information may be used as part of a log, possibly as a separate issue, as that has larger implications.Logging and exception handling go hand-in-hand when running any software at scale. These areas are very sensitive and highly specific. Given Feign’s place as a middleware, we must do our best to remain neutral and provide ways for users to manage logging and exception handling, delegating that responsibility and not be too restrictive or too opinionated.
The request here is quite simple, a better error message. However, given that this information will be consumed primarily via log files, we need to be very careful how to approach the structure of the message and we must provide a way to override our format. I’m suggesting that we approach this ask as follows:
Update the
FeignException
API to exposeRequest
andResponse
context information explicitly. Adding methods like the following:getRequestEndpoint()
getRequestMethod()
getRequestHeaders()
getRequestParameters()
getResponseStatusCode()
getResponseReasonCode()
getResponseAsString()
Update
FeignException#getMessage()
to format the information in a very simple, unstructured way, specifically to avoid imposing any structure on users.Refactor the
Logger
API to allow customization of these log messages when using Feign’s built in logging capability. It is here that users will be able to add any specific structure they need, like format it as JSON, limit the response, etc…Hi @finnetrolle
I’m sorry for the delay. I wrote some code clarify things. Can you look at https://github.com/OpenFeign/feign/pull/1095 ?
It is just an example. It just naively decodes the response body without any checks. But illustrates my idea.
All information is just visible in the exception’s
getMessage()
. So it’s clearly visible, what went wrong, in the log files.And also, the information propagates nicely, when wrapped with other business-like exceptions.
I’m aware that the approach with
LOGGER.info
is an option, too. But I am worried that I would need to code thisLOGGER.info(...)
all across the code. As an ‘everyday developer’, I would want to avoid writing the sameLOGGER.info()
in multiple places.