Fix exception handler overlap issue - add DomainError catch-all handler
**Problem:** Broad exception handlers created fragility where adding a new DomainError subclass without explicit registration would silently fall through to the generic exception handler, losing the specific error_code and metadata. **Solution:** 1. Import DomainError in main.py for explicit handler registration 2. Fix type hints in exception handlers from 'Exception' to specific types - NotFoundError handler now typed as 'NotFoundError' - BadRequestError handler now typed as 'BadRequestError' - ConflictError handler now typed as 'ConflictError' - DomainError handler now typed as 'DomainError' - ServiceUnavailableError handler now typed as 'ServiceUnavailableError' 3. Add DomainError as an explicit catch-all handler in the registration chain - Positioned after specific handlers, before HTTPException - Any unregistered DomainError subclass now gets correct error_code + metadata 4. Document the exception handler hierarchy with detailed comments 5. Update Backend-Development.md with handler hierarchy documentation 6. Update Architekture.md section 2.2 with exception handler details 7. Fix test expectations in test_main.py to verify ErrorResponse format **Impact:** Any new DomainError subclass now automatically gets correct HTTP 500 status, error_code, and metadata - even if developer forgets explicit handler. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -112,15 +112,25 @@ async def test_create_app_global_domain_exception_handlers() -> None:
|
||||
async with AsyncClient(transport=transport, base_url="http://test") as client:
|
||||
response = await client.get("/not-found")
|
||||
assert response.status_code == 404
|
||||
assert response.json() == {"detail": "Jail not found: 'ssh'"}
|
||||
data = response.json()
|
||||
assert data["code"] == "jail_not_found"
|
||||
assert data["detail"] == "Jail not found: 'ssh'"
|
||||
assert data["metadata"] == {"jail_name": "ssh"}
|
||||
assert "correlation_id" in data
|
||||
|
||||
response = await client.get("/bad-request")
|
||||
assert response.status_code == 400
|
||||
assert response.json() == {"detail": "invalid payload"}
|
||||
data = response.json()
|
||||
assert data["code"] == "config_validation_failed"
|
||||
assert data["detail"] == "invalid payload"
|
||||
assert "correlation_id" in data
|
||||
|
||||
response = await client.get("/server-error")
|
||||
assert response.status_code == 500
|
||||
assert response.json() == {"detail": "write failed"}
|
||||
data = response.json()
|
||||
assert data["code"] == "config_write_failed"
|
||||
assert data["detail"] == "write failed"
|
||||
assert "correlation_id" in data
|
||||
|
||||
|
||||
def test_create_app_disables_cors_by_default() -> None:
|
||||
|
||||
Reference in New Issue
Block a user