Skip to content

fix: correct error handling in read endpoints to return proper HTTP s…#163

Open
bhudevbhanpuriya wants to merge 1 commit into
istSOS:mainfrom
bhudevbhanpuriya:fix/read-endpoints-error-handling
Open

fix: correct error handling in read endpoints to return proper HTTP s…#163
bhudevbhanpuriya wants to merge 1 commit into
istSOS:mainfrom
bhudevbhanpuriya:fix/read-endpoints-error-handling

Conversation

@bhudevbhanpuriya
Copy link
Copy Markdown
Contributor

Summary

This PR fixes a critical bug in all read endpoints where a broad exception handler was incorrectly mapping all runtime failures to HTTP 404 Not Found, including database connection errors and internal server errors. This made it impossible for clients to distinguish between legitimate "not found" scenarios and actual backend failures.

Problem

All read endpoints in api/app/v1/endpoints/read/ had the following problematic pattern:

try:
    first_item = await anext(result)
    return StreamingResponse(...)
except Exception as e:
    return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, ...)

This caused several issues:

  • Database connection failures returned 404 instead of 503
  • Internal errors returned 404 instead of 500
  • No error logging, making debugging impossible
  • Clients couldn't implement proper retry logic
  • Production issues were masked as "not found" errors

Solution

Implemented specific exception handling to return appropriate HTTP status codes:

  • 404 Not Found: Only when query returns no results (StopAsyncIteration)
  • 503 Service Unavailable: For database connection issues
  • 500 Internal Server Error: For unexpected errors

Added proper logging for all exceptions to improve observability.

try:
    first_item = await anext(result)
    return StreamingResponse(...)
except StopAsyncIteration:
    return JSONResponse(status_code=status.HTTP_404_NOT_FOUND, ...)
except (asyncpg.PostgresConnectionError, asyncpg.TooManyConnectionsError):
    logger.exception("Database unavailable")
    return JSONResponse(status_code=status.HTTP_503_SERVICE_UNAVAILABLE, ...)
except Exception:
    logger.exception("Unexpected streaming error")
    return JSONResponse(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, ...)

Changes

Modified Files (10)

  • api/app/v1/endpoints/read/sensor.py
  • api/app/v1/endpoints/read/thing.py
  • api/app/v1/endpoints/read/datastream.py
  • api/app/v1/endpoints/read/observation.py
  • api/app/v1/endpoints/read/historical_location.py
  • api/app/v1/endpoints/read/feature_of_interest.py
  • api/app/v1/endpoints/read/location.py
  • api/app/v1/endpoints/read/observed_property.py
  • api/app/v1/endpoints/read/network.py
  • api/app/v1/endpoints/read/commit.py

Key Changes Per File

  • Added import logging and import asyncpg
  • Added logger = logging.getLogger(__name__)
  • Replaced broad except Exception with specific exception handlers
  • Added StopAsyncIteration handler for legitimate 404 cases
  • Added database exception handlers for 503 cases
  • Added generic exception handler with logging for 500 cases

Impact

Before

Scenario Response
No results 404
DB connection lost 404 (wrong)
Internal error 404 (wrong)
No logging N/A

After

Scenario Response
No results 404
DB connection lost 503 (correct)
Internal error 500 (correct)
All errors logged Yes

Benefits

  1. Correct HTTP semantics: Proper status codes enable appropriate client behavior
  2. Better observability: All errors are now logged with full stack traces
  3. Improved debugging: Developers can identify database vs application issues
  4. Better user experience: Clients can implement proper retry logic based on status codes

Breaking Changes

None. This only affects error responses, and the change makes them more correct according to HTTP standards.

Closes #161

…tatus codes

- Replace broad 'except Exception' with specific exception handlers
- Return 404 only for StopAsyncIteration (no results found)
- Return 503 for database connection errors
- Return 500 for unexpected internal errors
- Add logging for all exceptions to improve observability
- Apply fix consistently across all 10 read endpoints

Fixes issue where all runtime failures were incorrectly mapped to 404,
making it impossible to distinguish between legitimate 'not found' and
backend/service errors.
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.

Bug: Read Endpoints Return Incorrect 404 for All Errors

1 participant