codebase-error-handling
Skill0 starsChanged 6 months agoMITView on GitHub
Document the error handling, logging, and observability setup of a codebase — what error types exist, how errors propagate (thrown vs returned vs Result types), what logger is used and how, what observability tooling is integrated (Sentry, Datadog, OpenTelemetry), and how errors surface to the user. Use this skill when the user asks "how does error handling work here", "document the error patterns", "what's the logging setup", "explain the error flow", "how are errors reported", "what's the observability stack", or any variant focused on errors and logging rather than full architecture. The output is a single Markdown file capturing error type hierarchy, propagation conventions, logging library and format, observability tools, user-facing error surfaces (HTTP responses, SnackBars, dialogs, CLI exit codes), and recurring error-handling patterns — each documented with REAL examples copied from the actual codebase. This skill is narrow by design and produces ONLY the error handling reference. It does not cover architecture, naming, testing, or domain vocabulary — point the user to the relevant sister skill if they need those.
In this repository4 other files it gives its agents.
- codebase-conventionsSkill
- codebase-glossarySkill
- codebase-overviewSkill
- codebase-testing-guideSkill
The file
We split this skill into the rules it gives an agent
8 rules. About 0 are common, 7 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈7
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 9
Document the error handling, logging, and observability setup of a codebase.
- Distinctive: line 157
When you find an interesting error class, throw site, or catch block, read the file to copy a real snippet — don't paraphrase.
- Distinctive: line 161
Check for an existing docs location:
- Very specific: line 162
If docs/ exists, save as docs/error-handling.md
- Distinctive: line 171
Real examples only: Every section must include at least one real, copy-pasteable example.
- Distinctive: line 179
Distinguish layers: If frontend and backend handle errors differently (almost always true), structure the relevant sections to show both — …
- Distinctive: line 181
Don't drift in scope: Don't document architecture or testing.
- Distinctive: line 187
If you found swallowed errors, missing observability in some layer, or inconsistent log levels for similar conditions, call those out — …
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Codebase Error Handling
Document the error handling, logging, and observability setup of a codebase. The output answers: "If something goes wrong in this code — at any layer — what's the right way to throw, propagate, log, report, and surface it to the user?"
Scope
This skill is narrow by design. It covers ONLY:
- Error type hierarchy (custom error classes, error codes, Result/Either types)
- How errors propagate (thrown vs returned, where caught, where rethrown)
- Logging library, format, and conventions
- Observability tooling (Sentry, Datadog, OpenTelemetry, PostHog error tracking)
- User-facing error surfaces (HTTP responses, toasts/SnackBars, dialogs, CLI exit codes)
- Recurring error-handling patterns
For everything else, point the user to a sister skill: codebase-overview for architecture, codebase-conventions for naming, codebase-testing-guide for tests, codebase-glossary for domain vocabulary.
What to Produce
A Markdown file with the structure below. Every section must include real examples from the actual codebase — real error class declarations, real throw/catch sites, real logger calls, real Sentry capture calls.
# {Project Name} — Error Handling
> Generated by codebase-error-handling on {YYYY-MM-DD}
## Error Type Hierarchy
{Custom error classes/types defined in the codebase. If there's a base class with subclasses, draw the hierarchy. If there are error codes or enums, list them.}
**Real example — base + subclass:**
\```{language}
{Real error class declarations from the codebase, copied verbatim}
\```
**Where defined:** `{path/to/errors/file}`
## Error Flow
{How errors propagate through layers. Are exceptions thrown and caught at the boundary? Are errors returned as values (Result, Either, tuple)? Where is the central catch point — middleware, handler wrapper, top-level try/catch? Are there any "error funnel" utilities that wrap arbitrary work?}
**Real example — throw site:**
\```{language}
{Real throw/raise statement showing the convention}
\```
**Real example — catch site:**
\```{language}
{Real catch block showing how errors are handled at the boundary}
\```
## Logging
{Library (winston / pino / loguru / structlog / standard logging / log package / dart logger), format (JSON / plaintext / structured), levels in use, log destinations, correlation IDs or request IDs.}
**Logger config / setup:** `{path}`
**Real example — typical log call:**
\```{language}
{Real logger usage from the codebase}
\```
## Observability
{Error monitoring (Sentry / Bugsnag / Rollbar / Honeybadger), APM (Datadog / New Relic / OpenTelemetry), front-end analytics with error tracking (PostHog / LogRocket). For each, show how it's wired up and where errors are reported.}
**Sentry / observability init:** `{path}`
**Real example — error capture:**
\```{language}
{Real capture call from the codebase}
\```
## User-Facing Errors
{How errors reach the user. For backend: HTTP status code conventions, error response shape, error code field. For frontend: toast/SnackBar usage, dialog patterns, inline error display. For CLI: exit codes, stderr formatting.}
**Real example — error response shape (backend):**
\```{language}
{Real example of a serialised error response from the codebase}
\```
**Real example — user-facing error UI (frontend):**
\```{language}
{Real toast/SnackBar/dialog code}
\```
## Recurring Patterns
For each pattern detected, include a description, where it shows up, and a real snippet.
### {Pattern 1 — e.g., "Hono typed error handler"}
{Description}
**Where it shows up:** `{file 1}`, `{file 2}`
**Snippet:**
\```{language}
{Real code}
\```
### {Pattern 2}
...
## Inconsistencies & Notes
{Any places where errors are swallowed (`catch (e) {}` with nothing inside), inconsistent logging levels for similar conditions, mixed error styles in the same module, TODO/FIXME notes near catch blocks. Also flag if observability is present in some layers but not others — that's a real gap.}How to Scan
# Custom error classes (multi-language)
grep -rn "extends Error\|extends Exception\|class.*Error\|class.*Exception\|HttpError\|AppError\|CustomError" --include="*.ts" --include="*.tsx" --include="*.py" --include="*.go" --include="*.dart" --include="*.java" --include="*.rs" 2>/dev/null | head -20
# Throw / raise sites
grep -rn "throw new\|^[[:space:]]*throw \|^[[:space:]]*raise " --include="*.ts" --include="*.tsx" --include="*.py" --include="*.dart" 2>/dev/null | head -20
# Result / Either / Option types (functional error handling)
grep -rn "Result<\|Either<\|Option<\|Ok(\|Err(\|.unwrap()\|.expect(" --include="*.ts" --include="*.rs" --include="*.go" 2>/dev/null | head -10
# Top-level catch / error boundary
grep -rn "ErrorBoundary\|onError\|errorHandler\|.catch(\|except [A-Z]\|recover()" --include="*.ts" --include="*.tsx" --include="*.py" --include="*.go" --include="*.dart" 2>/dev/null | head -15
# Logging libraries
grep -rn "winston\|pino\|loguru\|structlog\|@logger\|console\.error\|console\.warn\|logger\.\|log\.[a-z]\|logging\.\|slog\." --include="*.ts" --include="*.tsx" --include="*.py" --include="*.go" --include="*.dart" 2>/dev/null | head -20
# Logger setup file (heuristic)
find . \( -name "logger.*" -o -name "logging.*" -o -name "log.*" \) -not -path '*/node_modules/*' -not -path '*/.git/*' 2>/dev/null | head -10
# Observability — Sentry
grep -rn "Sentry\.init\|Sentry\.captureException\|@sentry\|sentry_sdk\|sentry-flutter\|sentry-go" --include="*.ts" --include="*.tsx" --include="*.py" --include="*.go" --include="*.dart" 2>/dev/null | head -15
# Observability — Datadog / OTEL / Bugsnag / Rollbar
grep -rn "datadog\|dd-trace\|opentelemetry\|@opentelemetry\|Bugsnag\|Rollbar\|Honeybadger" --include="*.ts" --include="*.tsx" --include="*.py" --include="*.go" 2>/dev/null | head -10
# Frontend user-facing error surfaces
grep -rn "toast\.error\|showSnackBar\|SnackBar(\|Alert(\|errorDialog\|notification\.error" --include="*.ts" --include="*.tsx" --include="*.dart" 2>/dev/null | head -15
# Backend error responses
grep -rn "res\.status(\|c\.json.*error\|HttpException\|abort(\|fastify\.error\|@app\.errorhandler" --include="*.ts" --include="*.tsx" --include="*.py" 2>/dev/null | head -15
# Empty / swallowed catches
grep -rn "catch ([a-z]*) {}" --include="*.ts" --include="*.tsx" 2>/dev/null | head -5
grep -rn "except.*:.*pass\|except.*:.*$" --include="*.py" 2>/dev/null | head -5
# CLI exit codes
grep -rn "sys\.exit\|process\.exit\|os\.Exit\|exit(" --include="*.ts" --include="*.py" --include="*.go" 2>/dev/null | head -10When you find an interesting error class, throw site, or catch block, read the file to copy a real snippet — don't paraphrase. The literal code is the deliverable.
Where to Save
Check for an existing docs location:
- If
docs/exists, save asdocs/error-handling.md - If
documentation/exists, save asdocumentation/error-handling.md - If
.claude/exists, save as.claude/error-handling.md - Otherwise propose
docs/error-handling.mdand ask the user before creating
For monorepos with separate frontend/backend, ask the user whether to produce one combined doc or one per side — error handling often differs significantly across the boundary.
Principles
Real examples only. Every section must include at least one real, copy-pasteable example. Generic descriptions like "the project uses Sentry" without showing the actual init call and a capture site fail this skill's contract.
Cite locations. Include the file path with every example. The user should be able to open the file and see the convention in context.
Show the boundary. The most useful information in this doc is where errors get caught — the boundary between "errors propagate up" and "errors get handled." Find that boundary (middleware, route wrapper, error boundary, main try/catch) and document it explicitly.
Surface swallowed errors. catch (e) {} with empty body, except: pass without a comment, errors logged but not rethrown when they should be — flag these in "Inconsistencies & Notes." They're real bugs waiting to happen.
Distinguish layers. If frontend and backend handle errors differently (almost always true), structure the relevant sections to show both — don't force them into one description.
Don't drift in scope. Don't document architecture or testing. If observability ties into deployment (e.g., Sentry env detection from Firebase config), reference it briefly but don't expand on the deployment side.
After Producing
- Save the file to the chosen location.
- In chat, surface the 1–2 most surprising or non-obvious patterns — these are usually the ones that, when violated by a new contributor, cause production incidents.
- If you found swallowed errors, missing observability in some layer, or inconsistent log levels for similar conditions, call those out — that's signal the team will care about.
- Provide a path or link to the saved file.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

