## 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