rust-error-handling
Rust error-handling patterns and anti-patterns -- `unwrap()` in request hot paths, `panic!` instead of returning a `Result`, leaking error internals via…
Skill by MILTONADINA
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/miltonadina-rust-error-handling
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: backend, security
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/rust-error-handling
What's inside
- Skill name
rust-error-handling- Description
- Rust error-handling patterns and anti-patterns -- `unwrap()` in request hot paths, `panic!` instead of returning a `Result`, leaking error internals via `Debug` derive on error types containing privileged state. Patterns covered include `thiserror` for typed errors, `anyhow` for application-layer error propagation, and error-payload sanitization at API boundaries. Triggers on Rust error-prone code authoring (`unwrap`, `expect`, `panic!`, `Result<_, _>` patterns). General security hygiene at the language-runtime layer.
- License
- MIT
- Instructions
- 280 lines in SKILL.md · view on GitHub
Agent Skills spec issues
- name: "rust-error-handling" does not match folder "error-handling"
Files (1)
- SKILL.md
SKILL.md (first lines)
# Rust Error Handling
> This skill addresses **general security hygiene at the
> language-runtime layer** -- the patterns close common Rust failure
> modes (request-handler panics, leaky error responses, internal-state
> exposure via `Debug`) but they are NOT the load-bearing defense
> against any specific OWASP ASI / AST threat. The agent-specific
> defenses operate at different layers: prompt-injection-defense for
> ASI01/ASI04, Tool Misuse defenses (e.g., webhook idempotency) for
> ASI02. Rust error handling is the substrate that lets the OTHER
> defenses work without panicking the whole process.
**Tradeoff:** `unwrap()` is shorter than proper `Result` handling.
Each `unwrap` in a request path is a future production panic. The
discipline below trades line-count for crash-resistance.
---
## Why this matters
A Rust web service that panics on `unwrap()` fails the request. In a
`tokio` runtime the panic unwinds only the task serving that request:
the runtime catches it and every other task keeps running, and the
client receives a 500 only if a layer such as tower-http's
`CatchPanicLayer` converts the panic into a response. Built with
`panic = "abort"`, the same panic terminates the whole process. The
downstream effects are: lost requests, unclear
error attribution in logs, and -- if the panic's payload contains
privileged state (a database connection string, a JWT, a customer
email) -- accidental disclosure when the panic is logged.
The mitigation is structural: convert `unwrap()` / `panic!` paths to
`Result` returns that the caller can handle deliberately, derive
`Debug` carefully on error types that may carry sensitive payloads,
and sanitize the error response at the API boundary.
---
## Pattern 1 -- Typed errors with `thiserror`
Define one error enum per crate (or per logical module) using
`thiserror`. The enum variants name the failure modes the code can
encounter; their `Display` impls produce log-safe messages.
```rust
use thiserror::Error;
#[derive(Debug, Error)]
pub enum CheckoutError {
#[error("payment provider rejected the charge")]
PaymentRejected,
#[error("order {order_id} not found")]
OrderNotFound { order_id: String },
#[error("database error")]
Database(#[from] sqlx::Error),
#[error("internal: {0}")]
Internal(String),
}
```
Each handler returns `Result<T, CheckoutError>` and uses `?` for
propagation. The caller (API handler, CLI command) maps the typed
error to an HTTP status / exit code in one place.
```rust
pub async fn checkout(order_id: String) -> Result<Receipt, CheckoutError> {
let order = db::find_order(&order_id).await?; // ? propagates Database errors
let order = order.ok_or(CheckoutError::OrderNotFound { order_id })?;
let receipt = payment::charge(&order).await
.map_err(|_| CheckoutError::PaymentRejected)?;
Ok(receipt)
}
```
This pattern keeps the happy path readable AND maintains structured
error categories for downstream handling.
---
## Pattern 2 -- `anyhow` for application-layer error propagation
For binary crates (CLIs, services) where typed errors would add ceremony
without value, use `anyhow::Result<T>`. It wraps any error type and
provides `.context(...)` for adding human-readable trace info.
```rust
use anyhow::{Context, Result};
pub async fn run(args: Args) -> Result<()> {
let config = load_config(&args.config_path)
.with_context(|| format!("failed to load config from {}", args.config_path))?;
let pool = db::connect(&config.database_url).await
.context("failed to connect to database")?;
for migration in args.migrations {
apply(&pool, migration).await
.with_context(|| format!("migration {migration} failed"))?;
}
Ok(())
}
```
The `.context(...)` calls build a stack of trace messages. When an
error finally bubbles to `main()`, printing it produces a multi-line
trace that points at the operation, not just the leaf cause. This is
the closest Rust gets to Python tracebacks for application code.
`anyhow` is for application crates. Library crates should prefer
`thiserror` so consumers can pattern-match specific error variants.
---
## Pattern 3 -- Sanitize error payloads at the API boundaryFrom MILTONADINA/DevOPs, MIT.
More from MILTONADINA/DevOPs
- 0.565score
cost-attribution
MILTONADINA
Track per-client and per-feature LLM and cloud spend with cryptographic audit trail.
SkillAFreshness: AClaude Code +9 - 0.565score
proof-of-work
MILTONADINA
Produce structured proof artifacts for every completed claim.
SkillAFreshness: AClaude Code +9 - 0.565score
plan-decomposition
MILTONADINA
Break an approved spec into atomic, ordered, verifiable tasks before any code is written.
SkillAFreshness: AClaude Code +9 - 0.565score
multi-tool-failover
MILTONADINA
Manage session continuity when switching between Claude Code, Codex CLI, Cursor, Antigravity, Kiro, or local LLMs (OpenCode, Aider).
SkillAFreshness: AClaude Code +9 - 0.565score
goal-loop
MILTONADINA
Execute the spec-tests-implement-verify cycle for one atomic task at a time.
SkillAFreshness: AClaude Code +9 - 0.565score
baton-handoff
MILTONADINA
Write a complete handoff document at session end so the next agent (Claude Code, Codex, Cursor, Antigravity, Kiro, or local LLM) resumes exactly where this…
SkillAFreshness: AClaude Code +9 - 0.565score
observability-instrument
MILTONADINA
Add OpenTelemetry spans with user_id and tenant_id in baggage to any new code path that handles requests, runs agents, or performs billable operations.
SkillAFreshness: AClaude Code +9 - 0.565score
ears-spec-writing
MILTONADINA
Write requirement specifications in EARS (Easy Approach to Requirements Syntax) notation.
SkillAFreshness: AClaude Code +9 - 0.565score
openapi-first
MILTONADINA
Generate API code, types, validators, mock servers, and client SDKs from a single OpenAPI 3.1 specification.
SkillAFreshness: AClaude Code +9 - 0.561score
session-summary
MILTONADINA
Generate the end-of-session human-reviewable report.
SkillAFreshness: AClaude Code +9 - 0.561score
coppa-audit
MILTONADINA
Audit code, data flows, and UI for COPPA (Children's Online Privacy Protection Act) compliance.
SkillAFreshness: AClaude Code +9 - 0.560score
supabase-rpc-functions
MILTONADINA
Supabase RPC function security patterns -- SECURITY DEFINER with `SET search_path` discipline, `REVOKE EXECUTE FROM public` for least-privilege exposure…
SkillAFreshness: AClaude Code +9
Signals
- Stars
- 0
- Forks
- 0
- Open issues
- 12
- Last commit (this folder)
- Sep 25, 2026 (1 month ago)
- Last release
- Sep 23, 2026 (1 month ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/MILTONADINA/DevOPs
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from MILTONADINA
- 0.565score
baton-handoff
MILTONADINA
Write a complete handoff document at session end so the next agent (Claude Code, Codex, Cursor, Antigravity, Kiro, or local LLM) resumes exactly where this…
SkillAFreshness: AClaude Code +9 - 0.565score
observability-instrument
MILTONADINA
Add OpenTelemetry spans with user_id and tenant_id in baggage to any new code path that handles requests, runs agents, or performs billable operations.
SkillAFreshness: AClaude Code +9 - 0.565score
openapi-first
MILTONADINA
Generate API code, types, validators, mock servers, and client SDKs from a single OpenAPI 3.1 specification.
SkillAFreshness: AClaude Code +9 - 0.565score
ears-spec-writing
MILTONADINA
Write requirement specifications in EARS (Easy Approach to Requirements Syntax) notation.
SkillAFreshness: AClaude Code +9 - 0.565score
cost-attribution
MILTONADINA
Track per-client and per-feature LLM and cloud spend with cryptographic audit trail.
SkillAFreshness: AClaude Code +9 - 0.565score
goal-loop
MILTONADINA
Execute the spec-tests-implement-verify cycle for one atomic task at a time.
SkillAFreshness: AClaude Code +9
Cite this page
rust-error-handling skill. Agent Mart. https://agentmart.dev/skills/miltonadina-rust-error-handling (last updated 2026-10-24)