"""Tests for API error response envelope handlers.""" import pytest from fastapi import FastAPI from fastapi.testclient import TestClient from transcription.api.errors import register_error_handlers from transcription.errors import AppError from transcription.errors import ErrorCategory @pytest.mark.integration class TestApiErrorResponses: """Verify API-level error serialization and status mapping.""" def test_app_error_returns_structured_envelope(self): """AppError maps to policy envelope fields and status code.""" app = FastAPI() register_error_handlers(app) @app.get("/boom") def boom() -> dict[str, str]: raise AppError( "Bad upload payload", category=ErrorCategory.VALIDATION, suggestion="Upload a non-empty file", error_id="abc12345", ) client = TestClient(app) response = client.get("/boom") assert response.status_code == 400 payload = response.json() assert payload["error_id"] == "abc12345" assert payload["category"] == "validation_error" assert payload["message"] == "Bad upload payload" assert payload["suggestion"] == "Upload a non-empty file" assert "timestamp" in payload def test_unexpected_error_returns_internal_unexpected_envelope(self): """Unexpected exceptions map to internal_unexpected_error with 500.""" app = FastAPI() register_error_handlers(app) @app.get("/explode") def explode() -> dict[str, str]: raise RuntimeError("unexpected failure") client = TestClient(app, raise_server_exceptions=False) response = client.get("/explode") assert response.status_code == 500 payload = response.json() assert payload["category"] == "internal_unexpected_error" assert "error_id" in payload assert payload["suggestion"]