feat: auto-detect raised HTTPExceptions for OpenAPI docs#4619
feat: auto-detect raised HTTPExceptions for OpenAPI docs#4619Br1an67 wants to merge 6 commits intolitestar-org:mainfrom
Conversation
Add AST-based detection of HTTPException subclasses raised in route handlers. When a handler does not explicitly declare 'raises', the OpenAPI response schema generation now automatically scans the handler's source code for 'raise' statements and includes the corresponding error responses in the generated schema. This is opt-out: explicitly setting 'raises' on a handler disables auto-detection, giving full control to the developer. New module: litestar/_openapi/exception_detection.py Modified: litestar/_openapi/responses.py (integration point) Tests: tests/unit/test_openapi/test_exception_detection.py
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #4619 +/- ##
==========================================
- Coverage 97.88% 97.88% -0.01%
==========================================
Files 298 299 +1
Lines 15375 15432 +57
Branches 1730 1743 +13
==========================================
+ Hits 15050 15105 +55
- Misses 184 185 +1
- Partials 141 142 +1 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
- Remove unused import (fixes pre-commit lint failure) - Add tests for uninspectable callables and bare raise statements - Add test for attribute-style raise (module.Exception) - Add integration test for auto-detection in ResponseFactory - Replace non-deterministic assertion with proper test
Add tests for uncovered branches: - Subscript-style call func (neither ast.Name nor ast.Attribute) - Subscript-style raise (neither ast.Call nor ast.Name) - Duplicate exception skipped in create_responses()
|
Documentation preview will be available shortly at https://litestar-org.github.io/litestar-docs-preview/4619 |
provinzkraut
left a comment
There was a problem hiding this comment.
Thanks for this submission. I do have a few concerns:
Performance impact
Doing this for every handler can get very costly for bigger applications, as it could increase startup time drastically. One approach to mitigating this might be using tokenize instead of ast
User expectations
If we add a feature that does something automatically, users will expect to work everywhere. HTTPExceptions can be raised at every point during the request processing chain, for example in dependencies and guards. As a user, I would expect guards in particular to work, since they're part of the authorisation chain.
However, making this work everywhere is going to be quite tricky.
Hidden magic
In general, Litestar tries not to do too much magic, and be explicit about things. This design goes quite a bit against that.
Assuming the goal is "Ensure that error responses are properly documented", I think this might be better suited for a linter. We've talked about adding a check command to Litestar's CLI before, where something like this would be a natural fit.
…allables - Move inline import of HTTPException to top-level module imports - Add _resolve_callable() helper to handle bound methods, classmethods, staticmethods, and classes (inspects __init__) - Add tests for bound method and class callable detection Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace hasattr check + direct __func__ access with getattr fallback to satisfy pyright type checking. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Replace ast-based scanning with tokenize for lower overhead - Add OpenAPIConfig.auto_detect_exceptions (default: False) so the feature is explicitly opt-in - Update tests to enable the new config flag
|
Thanks for the thoughtful review — all valid concerns. I've pushed an update that addresses them:
If you'd still prefer this to live as a CLI |
Description
When a route handler raises
HTTPExceptionsubclasses but does not explicitly declare them via theraisesparameter, those error responses are currently missing from the generated OpenAPI schema.This PR adds AST-based auto-detection of raised
HTTPExceptionsubclasses in route handlers. The OpenAPI response generator now automatically scans handler source code forraisestatements targetingHTTPExceptionsubclasses and includes the corresponding error responses in the schema.Behavior:
raisesis not set on a handler → automatically detect raised exceptions via AST inspectionraisesis explicitly set → use only the declared exceptions (no auto-detection), preserving full developer controlChanges:
litestar/_openapi/exception_detection.pywithdetect_exceptions_from_handler()litestar/_openapi/responses.pyto call auto-detection increate_responses()tests/unit/test_openapi/test_exception_detection.pyCloses
Closes #2416
📚 Documentation preview 📚: https://litestar-org.github.io/litestar-docs-preview/4619