fix(backend/candidates): sanitize store error and task link validation reflections
Closed
AJ
15d ago+306+306+012345678901234567890123456789-3-3-0123456789
Failure-Class: none
Summary
Hardens error sanitization and prevents internal storage detail disclosure in the candidate lifecycle router (backend/routers/candidates.py):
-
Exception Detail Sanitization:
- In
backend/routers/candidates.py, caughtWorkstreamCandidateResolverUnavailableError, genericCandidateStoreError, andTaskLinkValidationErrorexceptions previously reflected raw error strings directly into HTTP responses viadetail=str(exc). - Raw exception strings can leak internal database structure, query parameters, or stack frames during database collisions or validator failures.
- Introduced
_sanitize_candidate_error(exc: Exception, fallback: str) -> strto log operation failures server-side (logger.warning) for debugging observability while safely returning constant, non-leaking error responses ("Workstream candidate resolver is temporarily unavailable","Candidate operation could not be completed","Invalid candidate task link parameters").
- In
-
Hermetic Unit Test Suite:
- Added
backend/tests/unit/test_candidates_error_sanitization.py(4 tests passing). - Verifies helper sanitization behavior, error code mapping, and static guarantee that no raw
detail=str(exc)leaks remain. - Covers behavioral simulation of
WorkstreamCandidateResolverUnavailableError,CandidateStoreError, andTaskLinkValidationErrorthrough hermetic mocks.
- Added
Product invariants affected
- INV-TASK-2
- INV-MEM-2
- INV-MEM-5
Verification
- Ran hermetic test suite:
python -m unittest backend/tests/unit/test_candidates_error_sanitization.py(4 tests passed). - Formatted with Black (
--line-length 120 --skip-string-normalization). - Verified zero raw exception string reflections remain in
backend/routers/candidates.py.
EVM Wallet Address: 0x3dB8636F9C32DeF9D96079A9eCF272E174093A11