name: error_handling rules: - Use explicit exceptions for domain/error classification (e.g., ProviderError, ValueError). - Prefer logging.exception when catching an exception where stack trace is useful. - Avoid broad except: clauses that swallow exceptions; if broad except is used for "best-effort" fallback, log at warning and include original exception context. - For public library-like functions, prefer raising typed exceptions instead of returning magic values ([], False) — only return safe defaults where documented. examples: - path: ai_provider.py excerpt: | ```python except requests.ConnectionError as exc: if attempt == retries: raise ProviderError( f"Connection error when calling provider: {exc}" ) from exc ... ``` note: mapping network error to ProviderError with re-raise chaining - path: pipeline/ai_provider_wrapper.py excerpt: | ```python except Exception: _logger.exception("Failed to append audit event for embedding failure") results[j] = None ``` note: logs and assigns None for failure; fallback behavior documented earlier in wrapper rule - path: similarity/compute.py excerpt: | ```python try: import duckdb except Exception: logger.exception("duckdb import failed; cannot load vectors") return 0 ``` note: defensive import handling and early return on failure anti_patterns: - Bad: Broad except without logging and without re-raising (silently hides bugs) remediation: Narrow exception types or at minimum log.exception() and re-raise or convert to a domain error if truly handled. example: | ```python try: do_work() except Exception: return [] # BAD: hides the root cause and returns an ambiguous default ``` - Bad: Mixing print() and logging for errors remediation: Replace print() calls with logger.* calls; use structured logging configuration.