fix(backend/candidates): sanitize store error and task link validation reflections

Closed
AJ
15d ago
+306-3

Failure-Class: none

Summary

Hardens error sanitization and prevents internal storage detail disclosure in the candidate lifecycle router (backend/routers/candidates.py):

  1. Exception Detail Sanitization:

    • In backend/routers/candidates.py, caught WorkstreamCandidateResolverUnavailableError, generic CandidateStoreError, and TaskLinkValidationError exceptions previously reflected raw error strings directly into HTTP responses via detail=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) -> str to 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").
  2. 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, and TaskLinkValidationError through hermetic mocks.

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