Rust Error Observability
Use this skill to make Rust service failures understandable to operators while
keeping user-facing responses safe. Treat error handling and telemetry as one
design surface.
Core Workflow
- Inventory error flows: handler return types, service/repository errors,
worker errors, middleware, logs, and tracing setup.
- Classify each error by purpose:
- Domain or validation outcome.
- Recoverable control flow.
- Operator diagnostic.
- User-facing HTTP response.
- Keep domain errors typed. Use
thiserror for expected branches that callers
should match on.
- Add context at infrastructure boundaries. Use
anyhow or opaque application
errors when callers should not match every dependency failure.
- Map errors to HTTP responses in one place per framework:
ResponseError,
Axum IntoResponse, or a small adapter function.
- Add structured spans before more log lines. Include stable diagnostic fields,
not raw payloads or secrets.
- Ensure errors are logged once. Prefer logging at the outer boundary where
request context is available.
- Test both the public response and the diagnostic path when behavior changed.
Error Boundary Rules
- Domain modules return domain errors, not HTTP status codes.
- Repository modules attach query or operation context, but do not log every
error.
- Handlers convert domain outcomes into response types and let unexpected
failures become a consistent 500.
- Background workers log failed job IDs, attempt counts, and next action.
- Avoid
unwrap, expect, or stringly map_err in service paths unless the
invariant is local and the panic message is useful.
Read references/error-boundaries.md when choosing between thiserror,
anyhow, opaque errors, and framework response adapters.
Tracing Rules
- Instrument request handlers, service methods, outbound clients, database
operations, and worker jobs at boundaries.
- Use
#[tracing::instrument(skip(...))] for request bodies, pools, clients,
passwords, tokens, and large values.
- Attach fields like request ID, user ID, tenant ID, job ID, upstream name, and
idempotency key when safe.
- Do not log secrets, cookies, password hashes, bearer tokens, or full PII.
Read references/tracing.md for spans, subscriber setup, and test logging.
Read references/secrets-and-pii.md before touching secret-bearing values.
HTTP Response Pattern
Keep response errors stable and intentional:
pub enum SubscribeError {
Validation(SubscribeValidationError),
Unexpected(anyhow::Error),
}
impl actix_web::ResponseError for SubscribeError {
fn status_code(&self) -> actix_web::http::StatusCode {
match self {
Self::Validation(_) => actix_web::http::StatusCode::BAD_REQUEST,
Self::Unexpected(_) => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,
}
}
}
The response body should be safe for users. The trace event should carry the
diagnostic context operators need.
Reference Files
references/error-boundaries.md: choosing error types and response adapters.
references/tracing.md: spans, fields, subscriber setup, and test output.
references/secrets-and-pii.md: redaction rules for secrets and sensitive
user data.
Source: hashgraph-online/awesome-codex-plugins → plugins/LVTD-LLC/skills/skills/rust-error-observability/SKILL.md
1---2name: rust-error-observability3description: Use when adding, changing, debugging, or reviewing Rust service error handling and observability, especially when separating domain errors from HTTP responses, adding thiserror/anyhow, implementing ResponseError or IntoResponse, adding tracing spans, redacting secrets, or diagnosing async failures.4---567# Rust Error Observability89Use this skill to make Rust service failures understandable to operators while10keeping user-facing responses safe. Treat error handling and telemetry as one11design surface.1213## Core Workflow14151. Inventory error flows: handler return types, service/repository errors,16 worker errors, middleware, logs, and tracing setup.172. Classify each error by purpose:18 - Domain or validation outcome.19 - Recoverable control flow.20 - Operator diagnostic.21 - User-facing HTTP response.223. Keep domain errors typed. Use `thiserror` for expected branches that callers23 should match on.244. Add context at infrastructure boundaries. Use `anyhow` or opaque application25 errors when callers should not match every dependency failure.265. Map errors to HTTP responses in one place per framework: `ResponseError`,27 Axum `IntoResponse`, or a small adapter function.286. Add structured spans before more log lines. Include stable diagnostic fields,29 not raw payloads or secrets.307. Ensure errors are logged once. Prefer logging at the outer boundary where31 request context is available.328. Test both the public response and the diagnostic path when behavior changed.3334## Error Boundary Rules3536- Domain modules return domain errors, not HTTP status codes.37- Repository modules attach query or operation context, but do not log every38 error.39- Handlers convert domain outcomes into response types and let unexpected40 failures become a consistent 500.41- Background workers log failed job IDs, attempt counts, and next action.42- Avoid `unwrap`, `expect`, or stringly `map_err` in service paths unless the43 invariant is local and the panic message is useful.4445Read `references/error-boundaries.md` when choosing between `thiserror`,46`anyhow`, opaque errors, and framework response adapters.4748## Tracing Rules4950- Instrument request handlers, service methods, outbound clients, database51 operations, and worker jobs at boundaries.52- Use `#[tracing::instrument(skip(...))]` for request bodies, pools, clients,53 passwords, tokens, and large values.54- Attach fields like request ID, user ID, tenant ID, job ID, upstream name, and55 idempotency key when safe.56- Do not log secrets, cookies, password hashes, bearer tokens, or full PII.5758Read `references/tracing.md` for spans, subscriber setup, and test logging.59Read `references/secrets-and-pii.md` before touching secret-bearing values.6061## HTTP Response Pattern6263Keep response errors stable and intentional:6465```rust66pub enum SubscribeError {67 Validation(SubscribeValidationError),68 Unexpected(anyhow::Error),69}7071impl actix_web::ResponseError for SubscribeError {72 fn status_code(&self) -> actix_web::http::StatusCode {73 match self {74 Self::Validation(_) => actix_web::http::StatusCode::BAD_REQUEST,75 Self::Unexpected(_) => actix_web::http::StatusCode::INTERNAL_SERVER_ERROR,76 }77 }78}79```8081The response body should be safe for users. The trace event should carry the82diagnostic context operators need.8384## Reference Files8586- `references/error-boundaries.md`: choosing error types and response adapters.87- `references/tracing.md`: spans, fields, subscriber setup, and test output.88- `references/secrets-and-pii.md`: redaction rules for secrets and sensitive89 user data.9091---9293**Source:** [`hashgraph-online/awesome-codex-plugins`](https://github.com/hashgraph-online/awesome-codex-plugins) → `plugins/LVTD-LLC/skills/skills/rust-error-observability/SKILL.md`