Fix API bugs surfaced by live tracing (422/400 instead of 500) - #2455
Open
Vinv-AI wants to merge 1 commit into
Open
Fix API bugs surfaced by live tracing (422/400 instead of 500)#2455Vinv-AI wants to merge 1 commit into
Vinv-AI wants to merge 1 commit into
Conversation
Several endpoints returned 500 (or crashed) on inputs that should be rejected with a 4xx. Fixes: - Pagination (items, users): skip/limit were unbounded, so negative values reached Postgres OFFSET/LIMIT and 500'd. Add shared SkipQuery (ge=0) and LimitQuery (ge=1, le=100) in app/api/params.py; out-of-range -> 422. - Private user create (dev-only /private router): email was a bare str, so an invalid address was committed and every later read 500'd on UserPublic (EmailStr). Use EmailStr (max_length=255) and password bounds (8-128) -> 422 before insert; drop the accepted-but-ignored is_verified (no column). - Private user create: duplicate email raised an unhandled UniqueViolation -> 500. Look up first and return 400; create via crud.create_user. - Password recovery HTML endpoint: response header name was "subject:", an invalid HTTP header name that raised RuntimeError. Use "subject". - Password recovery: send the email via BackgroundTasks so the HTTP response no longer waits on SMTP (enumeration-safe uniform response unchanged). Tests added for each case (invalid email, short password, duplicate email, negative skip, negative limit, valid recovery header, background/no-op email). Co-Authored-By: Vinv-AI <309466812+Vinv-AI@users.noreply.github.com>
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.
Pull Request
Discussion: #2454
Description
Several endpoints returned 500 (or crashed) on inputs that should be rejected
with a 4xx. This PR fixes them and adds tests for each case.
skip/limitwere unbounded, so negativevalues reached Postgres
OFFSET/LIMITand 500'd. Added sharedSkipQuery(
ge=0) andLimitQuery(ge=1, le=100) inapp/api/params.py; out-of-rangevalues now return 422.
/privaterouter):emailwas a barestr,so an invalid address was committed and every later read 500'd on
UserPublic(
EmailStr). Now usesEmailStr(max_length=255) and password bounds(
8–128) → 422 before insert; drops the accepted-but-ignoredis_verified(no such column).
UniqueViolation→ 500. Now looks up first and returns 400; creates via
crud.create_user."subject:",an invalid HTTP header name that raised
RuntimeError. Now"subject".BackgroundTasksso the HTTPresponse no longer waits on SMTP (the enumeration-safe uniform response is
unchanged).
No public/documented API changes. B1–B3 are on the
privaterouter, which isonly mounted when
FASTAPI_ENV == "development"(E2E/local).AI Disclaimer
Models: Composer 2.5 (via Cursor + VinvAI)
Prompt (paraphrased): apply the live-trace fix set (unbounded pagination → 422,
private-route email/password validation and duplicate handling, the invalid
subject:recovery header, and background-task SMTP) — verifying each bugagainst the current code first — and add a test for each case.
AI transcript
private.pybareemail: str+no dup check;
users.py/items.pyunboundedskip/limit;login.py"subject:"header and synchronoussend_email; confirmedis_verifiedhasno model column and the
privaterouter is dev-only).app/api/params.py(SkipQuery/LimitQuery);users.py/items.pyuse them;private.py(EmailStr+ bounds, duplicate → 400,crud.create_user);login.py(subjectheader,BackgroundTasks).negative skip (users); negative limit (items); valid recovery header,
background-vs-no-op email (login).
enumeration benefit; returning a preview for a non-existent user is wrong).
ruff checkandruff formatare clean. The pytest suite was NOT run locally (no Postgres available in this
environment) — see checklist note.
Checklist