from fastapi import FastAPI, HTTPException from fastapi.testclient import TestClient from app.api.problem_details import install_problem_details_handlers def test_structured_http_error_preserves_domain_code_and_recovery_fields(): app = FastAPI() install_problem_details_handlers(app) @app.get("/lease") async def expired_lease(): raise HTTPException( status_code=409, detail={ "code": "LEASE_EXPIRED", "message": "Agent lease has expired", "retryable": False, "related_refs": ["task-1"], "recovery_action": "claim_new_generation", "retry_after_seconds": None, }, ) response = TestClient(app).get("/lease") assert response.status_code == 409 assert response.headers["content-type"].startswith("application/problem+json") assert response.json() == { "type": "https://tjwater.example/problems/LEASE-EXPIRED", "title": "Conflict", "status": 409, "detail": "Agent lease has expired", "instance": "/lease", "code": "LEASE_EXPIRED", "trace_id": response.json()["trace_id"], "errors": [], "retryable": False, "related_refs": ["task-1"], "recovery_action": "claim_new_generation", "retry_after_seconds": None, }