Rust Error Handling Patterns
Custom Error Types with thiserror
#rust #error #thiserror #error-handling #custom-errors
Use thiserror for custom error types with clear error messages and automatic From implementations.
Good Example:
use Error;
pub type Result<T> = Result;Bad Example:
// String-based errors lose type information
pub type Result<T> = Result;
Rationale: Typed errors enable proper error handling at different levels. thiserror derives reduce boilerplate while maintaining clarity.
Best Practices:
- Create one error type per module or subsystem
- Use
#[from]for automatic conversion from dependency errors - Include contextual data in error variants
- Use descriptive error messages with
#[error("...")]
Result Propagation Pattern
#rust #error #result #question-mark #error-propagation
Use ? operator for clean error propagation. Add context with map_err or context when needed.
Good Example:
use ;
async Bad Example:
// Swallowing errors or converting to panics
async Rationale: Error context helps debugging without cluttering the happy path. anyhow::Context adds descriptive error chains.
Error Recovery Pattern
#rust #error #recovery #fallback #resilience
Implement fallback strategies for recoverable errors.
Good Example:
async Bad Example:
// Fails immediately without retry or fallback
async Rationale: Network and external service errors are often transient. Fallback strategies improve reliability.
Strategies:
- Fallback source: Alternative data source
- Retry with backoff: Exponential backoff for transient failures
- Default value: Return sensible default when data unavailable
- Cached value: Return stale data with warning
Early Return Pattern
#rust #error #early-return #validation #guard-clause
Validate inputs early and return errors before expensive operations.
Good Example:
Bad Example:
// Validates after expensive operations
Rationale: Fail fast on invalid input before consuming resources. This improves performance and prevents partial state changes.
Error Logging Pattern
#rust #error #logging #tracing #observability
Log errors at appropriate levels with context.
Good Example:
use ;
async Bad Example:
// No context, wrong log levels
async Rationale: Structured logging with context enables debugging in production. Different log levels indicate severity.
Log Levels:
error!: Failures that prevent operation completionwarn!: Recoverable errors or unexpected conditionsinfo!: Important state changesdebug!: Detailed diagnostic information
Result vs Option Pattern
#rust #error #result #option #type-choice
Choose between Result and Option based on whether absence is an error.
Use Result When:
// Failure needs explanation
Use Option When:
// Absence is normal, not an error
// Convert to Result when context is needed
Rationale: Option signals that absence is expected. Result signals that absence is an error requiring explanation.
Related Patterns
See also:
- [[async-patterns]] - Error handling in async contexts
- [[testing]] - Testing error conditions
- [[logging]] - Structured logging
- [[resilience]] - Circuit breakers and retry patterns