Skip to content

fix(security): SecurityMiddleware no longer retries self.app() on exception - #22

Merged
magi8101 merged 1 commit into
mainfrom
fix/security-middleware-double-invoke-issue-17
Sep 6, 2026
Merged

fix(security): SecurityMiddleware no longer retries self.app() on exception#22
magi8101 merged 1 commit into
mainfrom
fix/security-middleware-double-invoke-issue-17

Conversation

@magi8101

@magi8101 magi8101 commented Sep 6, 2026

Copy link
Copy Markdown
Member

Fixes #17. call caught any exception from _on_request and responded by calling self.app(request) a second time, meant to keep a buggy security check from crashing the pipeline. Every real subclass calls self.app(request) itself partway through, and since #16 that call essentially never raises anymore (the compiled middleware terminal already converts routing failures and handler exceptions to real Responses). So what this actually caught was a bug in a middleware's own post-processing after a successful downstream call — and silently re-ran the whole chain, handler included. Worse, the client sees the retry's response as a plain success, no sign anything ran twice.

Removed the catch. Added a regression test — confirmed it fails against the old code (handler runs twice, client sees 200) and passes now (runs once, client sees 500). 262/262 tests, mypy clean, ruff clean, verified in a fresh venv.

…eption

Fixes #17. __call__ caught any exception from _on_request and responded
by calling self.app(request) a second time -- meant to keep a buggy
security check from crashing the pipeline. But every real subclass calls
self.app(request) itself partway through _on_request, and since #16, that
call essentially never raises anymore (the compiled middleware terminal
already converts routing failures and handler-raised HTTPExceptions into
real Responses before they get back here). So what this actually caught
was a bug in a middleware's OWN post-processing after a successful
self.app(request) call -- e.g. mutating headers on the response it got
back -- and silently re-ran the entire downstream chain, handler included,
for one incoming request. Worse, the retry's response is what the client
sees, so a real bug there reads as a plain success with no indication
anything ran twice.

Removed the catch. Whatever's left after #16 (a bug in this middleware's
own code) should surface as a real error via the existing exception
handling, not get silently retried.

Added a regression test: confirmed it fails against the old code (a
handler with a side effect runs twice, client sees 200) and passes now
(runs once, client sees 500). 262/262 tests, mypy clean, ruff clean --
verified in a fresh venv matching CI's install steps.
Copilot AI lite review requested due to automatic review settings September 6, 2026 17:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@magi8101
magi8101 merged commit 26762ee into main Sep 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SecurityMiddleware.__call__ retries self.app(request) on any downstream exception

2 participants