Skip to content

Bug: Read Endpoints Return Incorrect 404 for All Errors #161

@bhudevbhanpuriya

Description

@bhudevbhanpuriya

What's happening

Every read endpoint wraps its streaming logic in a bare except Exception block and hardcodes 404 Not Found as the response , no matter what actually went wrong.

try:
    first_item = await anext(result)
    return StreamingResponse(...)
except Exception as e:
    return JSONResponse(
        status_code=status.HTTP_404_NOT_FOUND,
        content={"code": 404, "type": "error", "message": "Not Found"},
    )

So if the database goes down, the client gets 404. If there's an unhandled bug in the service layer, the client gets 404. The only case where 404 is actually correct ,no rows returned ,also gets 404. Everything looks the same from the outside.

Why it matters

Clients can't distinguish "no data" from "service is broken" .they'll retry or report a missing resource when the real problem is a backend outage.
Ops/monitoring is blind ,alerts keyed on 5xx errors will never fire for database failures coming through these endpoints.
Debugging is painful ,logs swallow the real exception; you just see 404s.

Root cause

StopAsyncIteration is the only exception that should map to 404 — it means the async generator returned nothing. Every other exception is either a database problem (→ 503) or an unexpected bug (→ 500).
The correct pattern already exists in the codebase:

except StopAsyncIteration:
    return JSONResponse(status_code=404, ...)
except (PostgresConnectionError, TooManyConnectionsError):
    return JSONResponse(status_code=503, ...)
except Exception as e:
    logger.exception(e)
    return JSONResponse(status_code=500, ...)

The individual read endpoints just never adopted it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions