generated from john/python-template
Error handling added to MVP according to error_handling.md guideline
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
## Step 7 Results: Error Handling Standardization and Operational Visibility
|
||||
|
||||
## Summary
|
||||
|
||||
Step 7 was implemented across the MVP runtime boundaries with a shared error taxonomy, actionable UI error surfacing, worker failure normalization, and API error envelope handling.
|
||||
|
||||
All required validation gates in `docs/step7.md` were executed and passed.
|
||||
|
||||
---
|
||||
|
||||
## Scope Delivered
|
||||
|
||||
### Implemented
|
||||
- Shared application error contract and taxonomy
|
||||
- Service-layer error normalization (upload + transcription)
|
||||
- UI error presentation helpers with suggested actions and error references
|
||||
- Worker failure persistence format with category/suggestion/error_id markers
|
||||
- API exception handlers for structured error responses
|
||||
- Targeted tests for new error contract behavior
|
||||
|
||||
### Not implemented in this step
|
||||
- External lane execution (`-m external`) was not required for Step 7 completion and was not run in this pass.
|
||||
|
||||
---
|
||||
|
||||
## Files Added
|
||||
|
||||
- `src/transcription/errors.py`
|
||||
- `src/transcription/api/errors.py`
|
||||
- `src/transcription/ui/error_presenter.py`
|
||||
- `tests/test_errors.py`
|
||||
- `tests/api/test_error_responses.py`
|
||||
- `docs/step7.md`
|
||||
|
||||
## Files Updated
|
||||
|
||||
- `src/transcription/app.py`
|
||||
- `src/transcription/services/upload.py`
|
||||
- `src/transcription/services/transcription.py`
|
||||
- `src/transcription/ui/upload_page.py`
|
||||
- `src/transcription/ui/jobs_page.py`
|
||||
- `src/transcription/worker.py`
|
||||
- `tests/services/test_upload.py`
|
||||
- `tests/services/test_transcription.py`
|
||||
- `tests/services/test_worker.py`
|
||||
- `tests/integration/test_pipeline_flow.py`
|
||||
- `uv.lock`
|
||||
|
||||
---
|
||||
|
||||
## Implementation Notes by Phase
|
||||
|
||||
### Phase A/B (Foundation)
|
||||
- Added `ErrorCategory` enum and `AppError` base type in `src/transcription/errors.py`.
|
||||
- Added helper utilities:
|
||||
- `new_error_id()`
|
||||
- `build_error_envelope(...)`
|
||||
- `classify_unexpected_error(...)`
|
||||
- `format_error_detail(...)`
|
||||
|
||||
### Phase C (Service/Provider normalization)
|
||||
- `UploadError` now extends `AppError` and includes category/suggestion/retriable metadata.
|
||||
- `PromptLoadError` and `TranscriptionError` now extend `AppError`.
|
||||
- Provider failures are mapped with deterministic category semantics (auth/payload/provider-failure cases).
|
||||
|
||||
### Phase D (UI visibility)
|
||||
- Added `src/transcription/ui/error_presenter.py`.
|
||||
- Upload and jobs pages now use centralized UI error rendering and summary helpers.
|
||||
- UI error paths now include more visible/actionable guidance and reference IDs.
|
||||
|
||||
### Phase E (Worker failure handling)
|
||||
- Worker now normalizes exception handling into structured persisted `error_detail` strings with:
|
||||
- category marker
|
||||
- suggestion marker
|
||||
- error_id marker
|
||||
- Logging now includes category/error_id context in failure paths.
|
||||
|
||||
### Phase F (API envelope)
|
||||
- Added `src/transcription/api/errors.py` and registered handlers in app factory.
|
||||
- AppError and unexpected exceptions now serialize to stable API envelopes with mapped status codes.
|
||||
|
||||
---
|
||||
|
||||
## Validation Commands and Outcomes
|
||||
|
||||
All commands were executed with `uv run python -m pytest ...` and completed successfully.
|
||||
|
||||
1. `uv run python -m pytest tests/test_errors.py -q` ✅
|
||||
2. `uv run python -m pytest tests/services/test_upload.py -q` ✅
|
||||
3. `uv run python -m pytest tests/services/test_transcription.py -q` ✅
|
||||
4. `uv run python -m pytest tests/providers/test_openrouter.py -q` ✅
|
||||
5. `uv run python -m pytest tests/services/test_worker.py -q` ✅
|
||||
6. `uv run python -m pytest tests/integration/test_pipeline_flow.py -q` ✅
|
||||
7. `uv run python -m pytest tests/api/test_error_responses.py -q` ✅
|
||||
8. `uv run python -m pytest tests/ui/test_upload_page.py -q` ✅
|
||||
9. `uv run python -m pytest tests/ui/test_jobs_page.py -q` ✅
|
||||
10. `uv run python -m pytest -m "not external" -q` ✅
|
||||
11. `uv run python -m pytest --collect-only -q` ✅
|
||||
12. `uv run python -m pytest -m unit -q` ✅
|
||||
13. `uv run python -m pytest -m integration -q` ✅
|
||||
14. `uv run python -m pytest tests/integration/test_pipeline_flow.py -q` ✅
|
||||
15. `uv run python -m pytest tests/ui/test_upload_page.py -q` ✅
|
||||
16. `uv run python -m pytest tests/ui/test_jobs_page.py -q` ✅
|
||||
17. `uv run python -m pytest -q` ✅
|
||||
|
||||
Observed warning (non-blocking): Starlette/FastAPI TestClient deprecation warning related to `httpx` package naming.
|
||||
|
||||
---
|
||||
|
||||
## Policy Alignment Check (`docs/error_handling.md`)
|
||||
|
||||
Aligned items:
|
||||
- Stable taxonomy categories are implemented.
|
||||
- Unexpected errors are normalized.
|
||||
- User-facing UI paths include actionable guidance and references.
|
||||
- Worker persistence includes trace-friendly failure detail.
|
||||
- API error responses are structured and category-aware.
|
||||
|
||||
Follow-up candidates:
|
||||
- Add richer UI tests that validate rendered suggested-action content end-to-end (current tests focus helper/service contracts).
|
||||
- Consider typed storage fields for error metadata instead of packed `error_detail` strings in a future schema revision.
|
||||
|
||||
---
|
||||
|
||||
## Step 7 Definition of Done Status
|
||||
|
||||
- [x] Shared error taxonomy implemented across MVP layers
|
||||
- [x] GUI error paths upgraded for visibility/actionability
|
||||
- [x] Worker failure persistence and log context standardized
|
||||
- [x] API error envelope handling added and tested
|
||||
- [x] Phase-level and full-suite validation gates passed
|
||||
- [x] Results documented in this report
|
||||
|
||||
Step 7 is complete.
|
||||
+267
@@ -0,0 +1,267 @@
|
||||
## 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
|
||||
Reference in New Issue
Block a user