-
-
Notifications
You must be signed in to change notification settings - Fork 348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhancement: Support for RFC 7807 / 9457 #3199
Comments
Discord Message
I think this shouldn't be difficult to implement. It's just the matter of deciding how the API would look like. We could create a plugin which would inject an exception handler that would then convert all the errors into the response following the spec. Or maybe take in a config value rfc9457 that will determine the default exception handler. I like the second approach of taking in a config value, because then users would be able to control it at all the layers so if they only want these problem details for a single controller or route, they could do that. NOTE: I only skimmed through the RFC, but 7807 has been obsoleted by 9457. |
Oops, I had both open as tabs in browser and used the wrong one when I wrote the issue up. RFC 9457 should obviously be the target goal.
@guacs Are you thinking something like a mapping? RFC9457Handler: TypeAlias = Callable[[Request, Exception], RFC9457Response]
def my_rfc9457_handler(request: Request, exception: Exception) -> RFC9457Response: ...
rfc9457_config: dict[type[Controller], RFC9457Handler] = {
# any controller missing from the list would not have RFC9457
# error support -- the default handler would be used instead
MyController: my_rfc9457_handler,
} Maybe the community could help produce a "default" RFC9457 handler for pydantic's ValidationError and some common ValueError, TypeError, LookupError, etc. It then becomes trivial to handle some exceptions as custom and return whatever the default handler would produce for others. What I haven't figured out or put much thought into yet is the URIs being referenced. Should a default RFC9457Controller be created that can be used for the To me, if the default handler and controller were to be created a plugin in another git repository would be best. Would the plugin just be middleware at that point? |
Plugin will be plugin :) Part of the code can look like this: def my_rfc9457_handler(request: Request, exception: Exception) -> RFC9457Response: ...
class RFC9457Plugin(InitPluginProtocol):
def on_app_init(self, app_config: AppConfig) -> AppConfig:
app_config.exception_handlers[HTTPException] = my_rfc9457_handler
return app_config
app = Litestar(plugins=[RFC9457Plugin()]) |
This is exactly what I had in mind. Though there are some questions like how to set up Another question is whether this plugin should be included in the main repo or whether this should be implemented as a separate library. Considering that this is an official RFC and an effort towards standardization, I'm kind of leaning towards including it the main litestar repo. |
I like this idea. Though within litestar, I think we should only catch any litestar specific exceptions rather than |
I would suggest I recently added support to Litestar for the "+json" media type suffix partially because I wanted to make use of problem details (so now "application/problem+json" gets json encoded automatically - I think problem details may even be used as an example in the docs). I would expect this feature to work by:
I think it is totally reasonable to convert the usual HTTPException to a problem details response because the problem details fields are optional, and there is some overlap (I think both have a "detail" field for example). |
I agree with all your points. I agree that the names you suggested are better since it makes it easier to understand than specifying some RFC which could at some point be superceded by another RFC. |
I read through the RFC and here are some initial thoughts/doubts I had regarding the implementation.
|
I haven't had time to read the full RFC, so I can't address all of that right now. I assumed that whenever litestar returns an error code with some json data, that could be replaced by the plugin with problem details ( As for the comment about OpenAPI schema generation - I considered suggesting that, because I know that this fastapi plugin does that. However, I felt that this was a separate issue. Litestar currently does not add every possible error response for each endpoint into the Open API schema, so I am not sure it makes sense that error responses should be put there just because of their media type. I would consider "add possible error responses to Open API schema" a separate issue from this. However, there may be something I am missing, of course. |
Ok, read it now. I think it would be fine if to either use "about:blank" as type, or to even go so far as to define some predefined types in litestar for e.g. validation errors and such things that are already handled inside litestar itself. |
This was my vision as well. Especially since we can, for example, use pydantic models as endpoint function parameter types for POST which can automatically generate 400 series status codes before even going into the function where the user can raise the appropriate exception type. |
How would the predefined types work? From what I understood, they should be (or it's preferred) for them to be resolvable URIs that's specific to your application. Or have I misunderstood the spec? |
For example something like This is an example from the RFC in the same style:
|
@bunny-therapist, @skewty I have a draft PR up with a very minimal implementation. If you have any feedback, that'd be great! |
Summary
A Boolean option to enable RFC7807 support might be a good way to enable this otherwise breaking change.
ie:
app = Litestar(rfc7807=True)
Perhaps some of the common exceptions (like ValueError) could have:
A new Exception class perhaps
JsonProblem(HTTPException)
which auto-includes "application/problem+json" in header and has fields for: type, title, status, etc.This would be nice to have and complement OpenAPI / Swagger support with the emerging standard for error responses.
Basic Example
No response
Drawbacks and Impact
No response
Unresolved questions
No response
Note
While we are open for sponsoring on GitHub Sponsors and
OpenCollective, we also utilize Polar.sh to engage in pledge-based sponsorship.
Check out all issues funded or available for funding on our Polar.sh dashboard
The text was updated successfully, but these errors were encountered: