## Step 7: Error Handling Standardization and Operational Visibility ## Objective Apply the canonical error policy from `docs/error_handling.md` to the MVP implementation so failures are: - consistently classified - visibly surfaced in the GUI - paired with suggested corrective actions - traceable through logs via error reference IDs - validated through deterministic tests after each phase This step extends MVP hardening by converting current ad hoc exception behavior into a stable cross-layer contract. --- ## Scope ### In scope - Introduce a shared application error contract and taxonomy implementation - Normalize service/provider exceptions into taxonomy categories - Improve GUI error visibility and suggested-action UX - Standardize worker failure persistence and logging context - Add API error-envelope policy hooks for current/future endpoints - Add targeted tests and phase-level/full-suite validation gates ### Out of scope - Major architecture rewrites (distributed queue, multi-service decomposition) - Post-MVP feature expansion unrelated to error handling - Full observability platform rollout (tracing backends, APM) --- ## Policy Source of Truth - Canonical policy document: `docs/error_handling.md` - If implementation and policy diverge, policy is authoritative and code/tests must be updated. --- ## Planned Deliverables ### Runtime code - `src/transcription/errors.py` *(new shared contract module)* - `src/transcription/ui/error_presenter.py` *(new UI error rendering helper)* - Updates to: - `src/transcription/services/upload.py` - `src/transcription/services/transcription.py` - `src/transcription/providers/openrouter.py` - `src/transcription/worker.py` - `src/transcription/ui/upload_page.py` - `src/transcription/ui/jobs_page.py` - `src/transcription/api/*` *(as needed for envelope/handlers)* ### Tests - `tests/test_errors.py` *(new shared error contract tests)* - updates/additions in: - `tests/services/test_upload.py` - `tests/services/test_transcription.py` *(add if missing)* - `tests/providers/test_openrouter.py` - `tests/services/test_worker.py` - `tests/ui/test_upload_page.py` - `tests/ui/test_jobs_page.py` - `tests/api/test_error_responses.py` *(new, if API handlers added)* ### Documentation - Update `docs/error_handling.md` only if implementation reveals policy gaps - Capture validation evidence in a Step 7 results artifact (`docs/step7-results.md`) --- ## Design and Policy Decisions 1. **Stable taxonomy contract** - Use policy categories as stable identifiers (`validation_error`, `user_input_error`, etc.). 2. **Actionable UX is mandatory** - User-visible errors must include a suggested course of action. 3. **Traceability by default** - Non-trivial errors include an `error_id` in both logs and user-facing output. 4. **Safe surface / rich logs** - UI/API show safe summaries; logs retain diagnostic detail and traceback. 5. **Deterministic verification cadence** - Targeted tests after each change batch, then phase-level regression gates. --- ## Implementation Plan + Checklist ## Phase A — Baseline Validation and Gap Confirmation - [ ] Run baseline tests before changes - [ ] Record baseline outputs and any known flaky behavior - [ ] Confirm current behavior against `docs/error_handling.md` requirements ### Validation gate - [ ] `uv run pytest -m "not external" -q` - [ ] `uv run pytest -q` ## Phase B — Shared Error Contract Foundation - [ ] Add `src/transcription/errors.py` with: - [ ] stable category enum - [ ] base `AppError` (category/message/suggestion/error_id/retriable) - [ ] helpers for error-id generation and fallback classification - [ ] Keep category names aligned with `docs/error_handling.md` ### Tests - [ ] Add `tests/test_errors.py` - [ ] category stability assertions - [ ] error_id creation behavior - [ ] fallback classification for unexpected exceptions ### Validation gate - [ ] `uv run pytest tests/test_errors.py -q` - [ ] `uv run pytest -m "not external" -q` ## Phase C — Service and Provider Normalization - [ ] Refactor upload service exceptions to shared taxonomy - [ ] Refactor transcription service exceptions to shared taxonomy - [ ] Normalize provider adapter failures into deterministic categories - [ ] Preserve causal chaining (`raise ... from exc`) ### Tests - [ ] Extend `tests/services/test_upload.py`: - [ ] empty payload category/suggestion - [ ] unsupported extension category/suggestion - [ ] persistence failure category mapping - [ ] Add/extend `tests/services/test_transcription.py`: - [ ] missing/empty prompt behavior - [ ] unsupported file type behavior - [ ] provider failure mapping behavior - [ ] Extend `tests/providers/test_openrouter.py`: - [ ] auth error mapping - [ ] malformed response mapping ### Validation gate - [ ] `uv run pytest tests/services/test_upload.py -q` - [ ] `uv run pytest tests/services/test_transcription.py -q` - [ ] `uv run pytest tests/providers/test_openrouter.py -q` - [ ] `uv run pytest -m "not external" -q` ## Phase D — GUI Visibility and Suggested Actions - [ ] Add `src/transcription/ui/error_presenter.py` - [ ] Update upload/jobs pages to use centralized error presentation - [ ] Ensure GUI surfaces: - [ ] user-safe message - [ ] suggested action - [ ] error reference ID - [ ] optional technical details panel - [ ] Replace raw `str(exc)` UX where policy requires safer messaging ### Tests - [ ] Extend `tests/ui/test_upload_page.py` for actionable error UX paths - [ ] Extend `tests/ui/test_jobs_page.py` for refresh/detail error guidance - [ ] Add `tests/ui/test_error_presenter.py` *(optional but recommended)* ### Validation gate - [ ] `uv run pytest tests/ui/test_upload_page.py -q` - [ ] `uv run pytest tests/ui/test_jobs_page.py -q` - [ ] `uv run pytest -m "not external" -q` ## Phase E — Worker Failure Persistence and Logging Context - [ ] Update worker failure handling to classify errors before persistence - [ ] Ensure failed jobs persist actionable, structured error detail - [ ] Add log context fields where available (`error_id`, `category`, `operation`, `job_id`) - [ ] Ensure retry semantics are explicit and bounded (or clearly documented as deferred) ### Tests - [ ] Extend `tests/services/test_worker.py`: - [ ] missing document failure contract - [ ] provider/transcription failure contract - [ ] persisted error detail includes category/suggestion/error_id markers - [ ] Validate integration failure flow in `tests/integration/test_pipeline_flow.py` ### Validation gate - [ ] `uv run pytest tests/services/test_worker.py -q` - [ ] `uv run pytest tests/integration/test_pipeline_flow.py -q` - [ ] `uv run pytest -m "not external" -q` ## Phase F — API Error Envelope Alignment (Current + Future Routes) - [ ] Add shared API error serialization utilities/handlers (as needed) - [ ] Ensure API responses can include: - [ ] `error_id` - [ ] `category` - [ ] `message` - [ ] `suggestion` - [ ] `timestamp` - [ ] Map categories to HTTP status guidance from `docs/error_handling.md` ### Tests - [ ] Add `tests/api/test_error_responses.py` *(if handlers added)* - [ ] Keep `tests/api/test_health.py` passing ### Validation gate - [ ] `uv run pytest tests/api/test_error_responses.py -q` *(if added)* - [ ] `uv run pytest tests/api/test_health.py -q` - [ ] `uv run pytest -m "not external" -q` ## Phase G — Final Regression and Documentation Closure - [ ] Reconcile implementation details with `docs/error_handling.md` - [ ] Update policy doc only where required by confirmed implementation learning - [ ] Capture execution evidence in `docs/step7-results.md` ### Final validation sequence (strict) - [ ] `uv run pytest --collect-only -q` - [ ] `uv run pytest -m unit -q` - [ ] `uv run pytest -m integration -q` - [ ] `uv run pytest -m "not external" -q` - [ ] `uv run pytest tests/integration/test_pipeline_flow.py -q` - [ ] `uv run pytest tests/ui/test_upload_page.py -q` - [ ] `uv run pytest tests/ui/test_jobs_page.py -q` - [ ] `uv run pytest -q` Optional: - [ ] `uv run pytest -m external -q` --- ## Guardrails - Do not weaken user-facing clarity to expose raw internals. - Do not introduce silent exception swallowing. - Do not break category-name stability without policy update. - Do not merge phase changes without passing that phase validation gate. - Keep targeted tests fast and deterministic; isolate external-provider tests under `external`. --- ## Definition of Done (Step 7) - [ ] Shared error taxonomy is implemented and used across MVP layers - [ ] GUI error experiences are visible, actionable, and traceable - [ ] Worker persists and logs failure context consistently - [ ] API error contract path is aligned for current/future endpoints - [ ] Phase-by-phase test gates pass - [ ] Full suite remains green (`uv run pytest -q`) - [ ] Step 7 results are documented with evidence --- ## PR Checklist (Step 7) ### Implementation - [ ] Added shared error contract module - [ ] Updated service/provider/worker/UI error handling paths - [ ] Added actionable GUI guidance for user-visible failures - [ ] Added error reference IDs for traceability ### Testing - [ ] Added/updated tests per phase scope - [ ] Ran targeted phase tests after each change batch - [ ] Ran `not external` regression at each phase boundary - [ ] Ran full suite before closeout ### Documentation and Evidence - [ ] `docs/error_handling.md` reviewed for alignment - [ ] `docs/step7-results.md` includes executed command outputs - [ ] Residual risks and deferred items explicitly recorded