Summary
When the PostgreSQL connection pool is fully saturated, Axum handlers return 500 Internal Server Error instead of 503 Service Unavailable. This breaks client retry logic since 503 is the standard signal for a temporary overload condition.
Observed Behaviour
HTTP/1.1 500 Internal Server Error
{"error": "pool timed out while waiting for an open connection"}
Expected Behaviour
HTTP/1.1 503 Service Unavailable
Retry-After: 5
{"error": "service temporarily unavailable", "retry_after_seconds": 5}
Implementation
In backend/src/error.rs, match the SQLx pool timeout error variant and map it to AppError::ServiceUnavailable:
sqlx::Error::PoolTimedOut => AppError::ServiceUnavailable { retry_after: 5 },
And in the error response serialiser, emit the Retry-After header.
Acceptance Criteria
Summary
When the PostgreSQL connection pool is fully saturated, Axum handlers return
500 Internal Server Errorinstead of503 Service Unavailable. This breaks client retry logic since503is the standard signal for a temporary overload condition.Observed Behaviour
Expected Behaviour
Implementation
In
backend/src/error.rs, match the SQLx pool timeout error variant and map it toAppError::ServiceUnavailable:And in the error response serialiser, emit the
Retry-Afterheader.Acceptance Criteria
503withRetry-Afterheaderretry_aftervalue is configurable