Open tuukkamustonen opened 9 months ago
Thinking out loud, for the rationale here, we often add error
or similar field to the responses:
{
"status_code": 409,
"detail": "User already has thing X",
"error": "AFP00146"
}
{
"status_code": 409,
"detail": "Some other case which leads to conflict",
"error": "AFP00147"
}
This will allow the caller to identify the error, due to the more granular error
compared to 409 status code.
Two things here:
error
to the OpenAPI spec (what this PR is about)Regarding (2), when you configure:
class UserAlreadyHasThingX(HTTPException):
status_code: Literal[409] = HTTP_409_CONFLICT
error: Literal["AFP00146"] = "AFP00146"
class SomeOtherConflict(HTTPException):
status_code: Literal[409] = HTTP_409_CONFLICT
error: Literal["AFP00147"] = "AFP00147" # or this could be `some_other_conflict`, as long as it's identifier
@get(..., raises=[UserAlreadyHasThingX, SomeOtherConflict])
def endpoint(): ...
This will generate oneOf
array in the OpenAPI schema, which is nice. All GUIs know how to show them, e.g..
The problem is, that both schemas are similar (except their description), so there's no benefit. We'd need to generate literal/enum AFP00146
/AFP00147
for the error
fields, so that reader would understand that despite the similar fields (in all error responses) the values (and descriptions) for certain errors are different.
Alternatively we could use detail
field to represent the error code (rather than human-readable string, what's usually put there).
However, Litestar would still need to pick those fields up when generating the schema. For example:
class UserAlreadyHasThingX(HTTPException):
status_code: int = HTTP_409_CONFLICT
error: Literal["user_already_has_thing_x"] = "user_already_has_thing_x"
This should rather generate something like:
A problem with this is that there's no room for human-readable error text now, as detail
was reserved for other purposes... would still need to add a custom field.
Anyway, customizing the schema generation should make this possible.
Summary
How
HTTPException
s get into OpenAPI spec is done is in https://github.com/litestar-org/litestar/blob/14759558cf231c61049fdd5b65a39eccb8841616/litestar/_openapi/responses.py#L280-L285The fields written (
status_code
,detail
,extra
) is hard-coded there.Allow generating the schema from a callable, that can be customized.
Basic Example
Just to give an idea:
Decoupling schema generation from the exception itself would work also for the builtin errors that Litestar might throw, like
ValidationException
.Drawbacks and Impact
No response
Unresolved questions
No response