-
Notifications
You must be signed in to change notification settings - Fork 38.9k
Description
Using Spring Boot 3.5.7 so org.springframework:spring-webmvc:6.2.12, but probably affects latest version as well given the documentation is clear about the expected behavior: https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-ann-rest-exceptions.html#mvc-ann-rest-exceptions-render
Doc states:
You can return ProblemDetail or ErrorResponse from any @ ExceptionHandler or from any @ RequestMapping method to render an RFC 9457 response. [...] The instance property of ProblemDetail is set from the current URL path, if not already set.
And the behavior I observe matches. However, the Problem RFC states:
The "instance" member is a JSON string containing a URI reference that identifies the specific occurrence of the problem. When the "instance" URI is dereferenceable, the problem details object can be fetched from it.
The example in section 3, for a POST /purchase call, contains a instance field with the value "/account/12345/msgs/abc".
So Spring MVC is not implementing the RFC correctly in this case.
Honestly, this is not a huge deal. Providing a link to "the specific occurrence of the problem" means maintaining machinery that most of the time isn't worth it just for this. Even if you wanted to build this into Spring, I don't know how it would reasonably work. Something like a ring of recent errors would work... for one instance of the service... for a limited time.
But I don't believe the default that Spring provides right now is useful either, in this case. The current URL, while it looks neat in the error response, is probably something the client already has access to. IMHO, it should have been left unset, but now this probably counts as breaking backcompat for end users (and consumers of the API).
Alternatively, maybe consider using an optional user-provided ProblemDetailInstanceProvider or something that takes the web context and current ProblemDetail and returns a value for the field? For backcompat, provide a default bean with the current behavior.
In my case, I'd just put the otel transaction ID in there (this is an accepted format in the RFC: "When the "instance" URI is not dereferenceable, it serves as a unique identifier for the problem occurrence that may be of significance to the server but is opaque to the client.").