Skip to content

fix: handle database connection errors gracefully - #91

Open
Mzsd wants to merge 2 commits into
developfrom
ms/handle-db-connection-exceptions
Open

Mzsd wants to merge 2 commits into
developfrom
ms/handle-db-connection-exceptions

Conversation

@Mzsd

@Mzsd Mzsd commented Sep 22, 2026

Copy link
Copy Markdown

Summary

Fixes a crash when the Postgres connection is dropped or interrupted (e.g. psycopg.errors.AdminShutdown, OperationalError). Previously this reached the generic unhandled exception handler and surfaced as a bare 500 with no indication it was a database issue, reproduced locally by running RYD against a real Postgres container and killing the backend serving its pooled connection mid-session, which crashed the request and produced a "Server Error" page on iati-account-web, matching the traceback in the issue.

Changes

  • Enabled pool_pre_ping on the FGA provider's SQLAlchemy engine, so a dead pooled connection is detected and silently replaced before use instead of failing the request that draws it from the pool. Verified this prevents the crash: killing the backend connection and repeating the same request no longer errors.
  • Added a dedicated exception handler for sqlalchemy.exc.DBAPIError, so any connection failure that still slips through is logged clearly as a database error and returned as a 503 rather than 500.
  • Added unit tests for the new handler.

Files changed

  • src/register_your_data_api/auth/fga/fga_provider_db.py
  • src/register_your_data_api/exception_handlers.py
  • tests/unit/test_exception_handlers.py

Related issues

Closes #69 - Psycopg database connection exceptions are not handled

@Mzsd Mzsd self-assigned this Sep 22, 2026
@Mzsd Mzsd linked an issue Sep 22, 2026 that may be closed by this pull request

@simon-20 simon-20 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.

This is good @Mzsd. I have just one request:

Returning 503 Service Unavailable implicitly tells the client they should try again later.

But some of the errors that are subclasses of sqlalchemy.exc.DBAPIError (e.g., IntegrityError) are not errors that will be fixed by retrying.

So, I would suggest:

  • separate off the handling of OperationError and AdminShutdown (and any other database errors you can find in the docs that are clearly runtime errors) and return 503 for them
  • handle DBAPIError after the above and return 500 for it

@Mzsd

Mzsd commented Sep 25, 2026

Copy link
Copy Markdown
Author

This is good @Mzsd. I have just one request:

Returning 503 Service Unavailable implicitly tells the client they should try again later.

But some of the errors that are subclasses of sqlalchemy.exc.DBAPIError (e.g., IntegrityError) are not errors that will be fixed by retrying.

So, I would suggest:

  • separate off the handling of OperationError and AdminShutdown (and any other database errors you can find in the docs that are clearly runtime errors) and return 503 for them
  • handle DBAPIError after the above and return 500 for it

Ok I will adjust that bit - thanks

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.

Psycopg database connection exceptions are not handled

2 participants