Rust Error Handling

SkillDev tools

Rust-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.

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)

  1. 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.
  2. fuse-ai-pilot:research-expert — confirm current thiserror / anyhow API before writing derives (verification chain: fuse-browser fast-path on docs.rs/thiserror and docs.rs/anyhow → Context7 → Exa).
  3. After writing, run fuse-ai-pilot:sniper and cargo clippy.

The rule

Crate kindToolWhy
Library (others depend on it)thiserrorTyped enum, #[derive(Error)], callers can match on variants
Application (binary, top level)anyhowanyhow::Result<T>, ? everywhere, .context() for breadcrumbs
Simple / dep-freehand-written std::error::ErrorNo dependency when one or two variants suffice

Critical Rules

  1. Never expose anyhow::Error in a library's public API. It erases the type, so callers cannot match or handle specific failures. Return a typed enum error. thiserror is designed to not appear in your public API — switching to/from a hand-written impl is not a breaking change.
  2. Applications use anyhow; libraries use thiserror. Do not pull anyhow into a reusable library's signatures.
  3. Add context at each layer in application code: .context("...") / .with_context(|| ...) turns "No such file or directory" into a traceable chain.
  4. #[from] for zero-boilerplate conversion, so ? lifts a source error into your enum. #[from] implies #[source] — never write both.
  5. Errors are values; panics are bugs. Use Result for anything a caller could reasonably recover from. Reserve panic!/unwrap/expect for broken invariants.

Reference Guide

Concepts

TopicReferenceLoad when
thiserror (libraries)thiserror-libraries.mdBuilding a typed error enum for a library API
anyhow (applications)anyhow-applications.mdHandling errors in a binary / top-level app
Error designerror-design.mdShaping enums, #[from] conversion, recoverable vs panic, the anyhow/thiserror boundary

Templates

TemplateLoad when
library-error.mdNeed a complete thiserror library error module
application-error.mdNeed a complete anyhow application entry point with context

Validation Checklist

  • Library errors are a typed enum deriving thiserror::Error — no anyhow in the public API
  • Application code returns anyhow::Result<T> and adds .context(...)
  • #[from] used for source conversions; no redundant #[source] alongside it
  • ? used instead of unwrap() on fallible values
  • Panics only guard genuine invariants, with a reason
  • cargo clippy clean, 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