Add coverage tests for core exceptions + structure utilities (#722)#158
Open
tmgbedu wants to merge 1 commit into
Open
Add coverage tests for core exceptions + structure utilities (#722)#158tmgbedu wants to merge 1 commit into
tmgbedu wants to merge 1 commit into
Conversation
Cover the FastAPI exception handlers (HTTPExceptionHandler debug/production rendering, ValidationExceptionHandler JSON vs redirect negotiation), the core ExceptionHandler dispatch/report/render paths, the RequestModel signature synthesis, and the data-structure helpers in utils/structures. Per-file coverage: - fastapi/exceptions.py 16% -> 100% - exceptions/handler.py 39% -> 100% - fastapi/requests/model.py 42% -> 100% - utils/structures.py 22% -> 89% Tests only; no framework source changed. Total suite coverage 72%.
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
tmgbedu
commented
Jul 9, 2026
tmgbedu
left a comment
Contributor
Author
There was a problem hiding this comment.
Review verdict: APPROVE ✅ (test-only coverage PR) — cannot self-approve via GitHub, so leaving as a comment.
Reviewed all 4 new test files against the actual source under test. No framework source changed.
Verified:
- Tests assert real behavior, not tautologies — each maps to a concrete branch in the source (report dispatch priority: custom reporter → handler.report → report_exception; render fallbacks; debug vs prod HTTP rendering; content-negotiation 422-vs-303 redirect; RequestModel signature synthesis Form/Query defaults;
validated()falsy-drop;load/data_*helpers). - All external deps mocked/faked —
Container.instance,Logger.error,atexit.register,sys.excepthookpatched; filesystem viatmp_path; no live app/session/network/DB. Theinstall()test restoressys.excepthookin afinally, so no global state leaks. - CI green — Pytest pass, Ruff pass.
- Coverage confirmed locally (matches task claims exactly): handler.py 16→100%, fastapi/exceptions.py →100%, requests/model.py →100%, utils/structures.py 22→89%. The 4 remaining lines in
structures.py(37–41) are an unreachableexcept KeyErrorbranch —getattrraisesAttributeError, neverKeyError, so it cannot be exercised. Accurately reported, not a gap in the tests.
Non-blocking FYI (pre-existing, not introduced here): that dead except KeyError in structures.load() should probably be except AttributeError — worth a separate follow-up task, out of scope for this test-only PR.
Not merging per standing order — maintainer's decision.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds unit tests (tests only — no framework source changed) to raise coverage for the core exception-handling and structure-utility modules called out in task #722.
What's covered
fastapi/exceptions.py—HTTPExceptionHandlerdebug vs. production rendering (trace payload / "Server Error");ValidationExceptionHandlercontent negotiation: JSON 422 viaaccept/content-type, non-JSON redirect with session flashing, and redirect-to-root without a session.exceptions/handler.py— registration APIs, MRO-based handler resolution, report dispatch (custom reporter → handler.report → logger → stderr),_build_contextwith/without debug traceback, asyncrender/handlepaths, and theexcepthook/installwiring.fastapi/requests/model.py—RequestModel.__pydantic_init_subclass__signature synthesis (Form-required, Form-with-default, Query fields) and thevalidated()falsy filter.utils/structures.py—load(module/attribute load, file-load failure returningNonevs. raisingLoaderNotFound), and the dotteddata/data_get/data_sethelpers.All external dependencies (container, logger,
atexit, filesystem, request/exception objects) are faked or patched — no live app, DB, session middleware, or network.Coverage (per file)
fastapi/exceptions.pyexceptions/handler.pyfastapi/requests/model.pyutils/structures.pyutils/structures.py's remaining lines are an unreachableexcept KeyErrorbranch (getattrraisesAttributeError, neverKeyError).Verification
fail_under = 68).ruff checkandruff format --checkclean.