Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Error Handling Best Practices

This document outlines the error handling patterns and practices used throughout the Eidetica codebase, focusing on structured errors, ergonomic APIs, and maintainable error propagation.

Core Error Architecture

1. Unified Result Type

Eidetica uses a unified Result<T> type across the entire codebase with automatic conversion between module-specific errors and the main error type. This provides consistent error handling and a single import for Result type throughout the codebase.

2. Module-Specific Error Types

Each module defines its own structured error type with semantic helpers. Error types include contextual information and helper methods for classification (e.g., is_authentication_error(), is_permission_denied()).

Error Design Patterns

1. Semantic Error Classification

Provide helper methods that allow callers to handle errors semantically, such as is_not_found(), is_storage_error(), or is_corruption_error(). This enables clean error handling based on error semantics rather than type matching.

2. Contextual Error Information

Include relevant context in error variants, such as available options when something is not found, or specific reasons for failures. This debugging information helps users understand what went wrong and can assist in error recovery.

3. Error Conversion Patterns

Use #[from] and #[error(transparent)] for zero-cost error conversion between module boundaries. This allows wrapping errors with additional context or passing them through directly.

4. Non-Exhaustive Error Enums

Use #[non_exhaustive] on error enums to allow adding new error variants in the future without breaking existing code.

Error Handling Strategies

1. Early Return with ? Operator

Use the ? operator for clean error propagation, validating preconditions early and returning errors as soon as they occur.

2. Error Context Enhancement

Add context when propagating errors up the call stack by wrapping lower-level errors with higher-level context that explains what operation failed.

3. Fallible Iterator Patterns

Handle errors in iterator chains gracefully by either failing fast on the first error or collecting all results before handling errors, depending on the use case.

Authentication Error Patterns

1. Permission-Based Errors

Structure authentication errors to be actionable by including what permission was required, what the user had, and potentially what options are available.

2. Security Error Handling

Be careful not to leak sensitive information in error messages. Reference resources by name or ID rather than content, and avoid exposing internal system details.

Performance Considerations

1. Error Allocation Optimization

Minimize allocations in error creation by using static strings for fixed messages and avoiding unnecessary string formatting in hot paths.

2. Error Path Optimization

Keep error paths simple and fast by deferring error creation until actually needed, using closures with ok_or_else() rather than ok_or().

Testing Error Conditions

1. Error Testing Patterns

Test both error conditions and error classification helpers. Verify that error context is preserved through the error chain and that error messages contain expected information.

2. Error Helper Testing

Test semantic error classification helpers to ensure they correctly identify error categories and that the classification logic remains consistent as error types evolve.

Common Anti-Patterns

  • String-based errors - Avoid unstructured string errors that lack context
  • Generic error types - Don't use overly generic errors that lose type information
  • Panic on recoverable errors - Return Result instead of using unwrap() or expect()
  • Leaking sensitive information - Don't expose internal details in error messages

Migration Guidelines

When updating error handling, maintain error semantics, add context gradually, test error paths thoroughly, and keep documentation current.

Summary

Effective error handling in Eidetica provides:

  • Structured error types with rich context and classification
  • Consistent error patterns across all modules
  • Semantic error helpers for easy error handling in calling code
  • Zero-cost error conversion between module boundaries
  • Performance-conscious error creation and propagation
  • Testable error conditions with comprehensive coverage

Following these patterns ensures errors are informative, actionable, and maintainable throughout the codebase evolution.