Rust Error Handling
SkillDev toolsRust-specific error handling patterns, building on the base error handling skill. Demonstrates the 'extends' composition feature.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Rust Error Handling skill
What this skill tells your AI
The instructions your AI receives, as published by dicklesworthstone/remote_compilation_helper in skills/examples/rust-error-handling/SKILL.md and read by ahel’s review.
It also covers the recoverable-errors-vs-panics decision — Result for anything a caller could reasonably recover from, panic!/unwrap/expect reserved for broken invariants — and the rule that anyhow::Error must never leak into a library's public API.
Out of scope: general ownership/borrowing design belongs to rust-core-language; async-runtime-specific error handling is not covered here.
Rust Error Handling
The consensus split: thiserror for libraries, anyhow for applications. A library
exposes a typed error its callers can match; an application wants one ergonomic error
type and rich context. Getting this boundary right is the whole discipline.
Agent Workflow (MANDATORY)
- fuse-ai-pilot:explore-codebase — is this crate a library (published API, other code depends on it) or a binary/application? That answer picks the tool.
- fuse-ai-pilot:research-expert — confirm current
thiserror/anyhowAPI before writing derives (verification chain: fuse-browser fast-path ondocs.rs/thiserroranddocs.rs/anyhow→ Context7 → Exa). - After writing, run fuse-ai-pilot:sniper and
cargo clippy.
The rule
| Crate kind | Tool | Why |
|---|---|---|
| Library (others depend on it) | thiserror | Typed enum, #[derive(Error)], callers can match on variants |
| Application (binary, top level) | anyhow | anyhow::Result<T>, ? everywhere, .context() for breadcrumbs |
| Simple / dep-free | hand-written std::error::Error | No dependency when one or two variants suffice |
Critical Rules
- Never expose
anyhow::Errorin a library's public API. It erases the type, so callers cannot match or handle specific failures. Return a typedenumerror. thiserror is designed to not appear in your public API — switching to/from a hand-written impl is not a breaking change. - Applications use
anyhow; libraries usethiserror. Do not pullanyhowinto a reusable library's signatures. - Add context at each layer in application code:
.context("...")/.with_context(|| ...)turns "No such file or directory" into a traceable chain. #[from]for zero-boilerplate conversion, so?lifts a source error into your enum.#[from]implies#[source]— never write both.- Errors are values; panics are bugs. Use
Resultfor anything a caller could reasonably recover from. Reservepanic!/unwrap/expectfor broken invariants.
Reference Guide
Concepts
| Topic | Reference | Load when |
|---|---|---|
| thiserror (libraries) | thiserror-libraries.md | Building a typed error enum for a library API |
| anyhow (applications) | anyhow-applications.md | Handling errors in a binary / top-level app |
| Error design | error-design.md | Shaping enums, #[from] conversion, recoverable vs panic, the anyhow/thiserror boundary |
Templates
| Template | Load when |
|---|---|
| library-error.md | Need a complete thiserror library error module |
| application-error.md | Need a complete anyhow application entry point with context |
Validation Checklist
- Library errors are a typed
enumderivingthiserror::Error— noanyhowin the public API - Application code returns
anyhow::Result<T>and adds.context(...) -
#[from]used for source conversions; no redundant#[source]alongside it -
?used instead ofunwrap()on fallible values - Panics only guard genuine invariants, with a reason
-
cargo clippyclean, sniper passed
Signals
- GitHub stars
- 60
- Forks
- 4
- Last commit
- Sep 2026
Others that do the same job
Advanced
- Catalog kind
- skill
- Gateway key
rust-error-handling- Source
- github.com/dicklesworthstone/remote_compilation_helper