| name | python-error-handling |
| description | Design or review general Python exception handling. Use this when choosing custom errors, translation boundaries, chaining, and when failures should propagate. |
Purpose
Choose clear, semantic Python error-handling rules without mixing in framework or architecture-specific mapping.
Trigger / When to use
Use this skill when:
- designing a project or package error hierarchy
- deciding when to raise a custom error, keep a built-in, or let a failure propagate
- reviewing broad catches, silent fallbacks, exception translation, or benign suppression
Do not use this skill when:
- the task is mainly about logging, observability, retry policy, or HTTP/framework exception mapping
- the task is mainly about DDD layer-specific error translation
- the task is mainly about
ExceptionGroup, asyncio.CancelledError, or multi-error aggregation
Inputs
- whether the failure is business/package meaning or programmer misuse
- whether the boundary is internal or public
- whether the API contract is optional or error-signaling
- whether the failure is known and controllable
- the supported Python version baseline
Process
- Define one custom root error that inherits from
Exception; add topic-level base errors only when grouping or a stable catch boundary justifies them.
- Use semantic custom errors for known business or package failures; leave programmer misuse and obvious bugs as built-ins such as
TypeError or ValueError.
- Catch only known, controllable failures and translate them once at the first boundary that can add real meaning.
- Preserve the cause with
raise CustomError(...) from exc; avoid from None except for narrow boundary cases that intentionally hide low-level detail.
- Reject broad catches, silent
None / False fallback, and untyped except: pass; allow only narrow benign suppression with explicit intent.
- Keep the first draft on synchronous single-exception flows, and mention Python-version limits when newer exception features are out of scope.
Examples
- Positive: Catch a low-level
ValueError once at a package boundary and raise InvalidConfigError from it; return None only for an explicit lookup-miss API.
- Negative: Re-wrap the same failure at every layer, leak random built-ins from a public API for known business failures, or hide errors behind
except Exception and empty fallback values.
Outputs
- a review-ready general Python error-handling rule set or skill draft
- defaults for error hierarchy, translation, propagation, and benign suppression
- local examples for common cases, anti-patterns, and scope boundaries
Boundaries
- Do not use Python's built-in
BaseException as the application or package root error.
- Do not define logging timing, retry policy, or framework-specific exception mapping.
- Do not cover
ExceptionGroup, asyncio.CancelledError, or multi-error aggregation in the first draft.
Local references
examples.md: hierarchy examples, translation rules, anti-patterns, and Python-version scope notes