ipfrs_core/
error.rs

1//! Error types for IPFRS operations.
2//!
3//! This module provides a unified error type ([`enum@Error`]) and result alias
4//! ([`Result`]) used throughout the IPFRS crate family.
5//!
6//! # Error Categories
7//!
8//! Errors are categorized by their source:
9//! - **I/O errors** - File system and network I/O failures
10//! - **Data errors** - Invalid blocks, CIDs, or serialization issues
11//! - **Not found** - Missing blocks, peers, or resources
12//! - **Protocol errors** - IPFS protocol violations
13//!
14//! # Example
15//!
16//! ```rust
17//! use ipfrs_core::{Error, Result, Block};
18//! use bytes::Bytes;
19//!
20//! fn process_block(data: &[u8]) -> Result<Block> {
21//!     if data.is_empty() {
22//!         return Err(Error::InvalidInput("empty data".to_string()));
23//!     }
24//!     Block::new(Bytes::copy_from_slice(data))
25//! }
26//! ```
27
28use thiserror::Error;
29
30/// Convenient result type for IPFRS operations.
31pub type Result<T> = std::result::Result<T, Error>;
32
33/// Unified error type for IPFRS operations.
34///
35/// This enum captures all error conditions that can occur in IPFRS,
36/// providing detailed context through error messages.
37#[derive(Debug, Error)]
38pub enum Error {
39    /// File system or network I/O error
40    #[error("IO error: {0}")]
41    Io(#[from] std::io::Error),
42
43    /// Requested block was not found in storage
44    #[error("Block not found: {0}")]
45    BlockNotFound(String),
46
47    /// CID parsing, generation, or validation error
48    #[error("CID error: {0}")]
49    Cid(String),
50
51    /// Data serialization error (CBOR, JSON, etc.)
52    #[error("Serialization error: {0}")]
53    Serialization(String),
54
55    /// Data deserialization error (CBOR, JSON, etc.)
56    #[error("Deserialization error: {0}")]
57    Deserialization(String),
58
59    /// Network communication error
60    #[error("Network error: {0}")]
61    Network(String),
62
63    /// Storage backend error (disk, memory, S3, etc.)
64    #[error("Storage error: {0}")]
65    Storage(String),
66
67    /// Encryption or decryption error
68    #[error("Encryption error: {0}")]
69    Encryption(String),
70
71    /// Data validation error (malformed blocks, invalid sizes, etc.)
72    #[error("Invalid data: {0}")]
73    InvalidData(String),
74
75    /// Invalid user input or parameters
76    #[error("Invalid input: {0}")]
77    InvalidInput(String),
78
79    /// Requested resource not found
80    #[error("Not found: {0}")]
81    NotFound(String),
82
83    /// IPFS protocol violation or incompatibility
84    #[error("Protocol error: {0}")]
85    Protocol(String),
86
87    /// Feature not yet implemented
88    #[error("Not implemented: {0}")]
89    NotImplemented(String),
90
91    /// Unexpected internal error (possible bug)
92    #[error("Internal error: {0}")]
93    Internal(String),
94
95    /// System initialization or setup error
96    #[error("Initialization error: {0}")]
97    Initialization(String),
98
99    /// Signature or cryptographic verification error
100    #[error("Verification error: {0}")]
101    Verification(String),
102}
103
104impl Error {
105    /// Check if this is an I/O error
106    #[inline]
107    pub const fn is_io(&self) -> bool {
108        matches!(self, Error::Io(_))
109    }
110
111    /// Check if this is a block not found error
112    #[inline]
113    pub const fn is_not_found(&self) -> bool {
114        matches!(self, Error::BlockNotFound(_) | Error::NotFound(_))
115    }
116
117    /// Check if this is a serialization/deserialization error
118    #[inline]
119    pub const fn is_serialization(&self) -> bool {
120        matches!(self, Error::Serialization(_) | Error::Deserialization(_))
121    }
122
123    /// Check if this is a network error
124    #[inline]
125    pub const fn is_network(&self) -> bool {
126        matches!(self, Error::Network(_))
127    }
128
129    /// Check if this is a storage error
130    #[inline]
131    pub const fn is_storage(&self) -> bool {
132        matches!(self, Error::Storage(_))
133    }
134
135    /// Check if this is a validation error
136    #[inline]
137    pub const fn is_validation(&self) -> bool {
138        matches!(self, Error::InvalidData(_) | Error::InvalidInput(_))
139    }
140
141    /// Check if this is a CID-related error
142    #[inline]
143    pub const fn is_cid(&self) -> bool {
144        matches!(self, Error::Cid(_))
145    }
146
147    /// Check if this is a verification error
148    #[inline]
149    pub const fn is_verification(&self) -> bool {
150        matches!(self, Error::Verification(_))
151    }
152
153    /// Get a human-readable error category name
154    pub const fn category(&self) -> &'static str {
155        match self {
156            Error::Io(_) => "io",
157            Error::BlockNotFound(_) => "not_found",
158            Error::Cid(_) => "cid",
159            Error::Serialization(_) => "serialization",
160            Error::Deserialization(_) => "deserialization",
161            Error::Network(_) => "network",
162            Error::Storage(_) => "storage",
163            Error::Encryption(_) => "encryption",
164            Error::InvalidData(_) => "invalid_data",
165            Error::InvalidInput(_) => "invalid_input",
166            Error::NotFound(_) => "not_found",
167            Error::Protocol(_) => "protocol",
168            Error::NotImplemented(_) => "not_implemented",
169            Error::Internal(_) => "internal",
170            Error::Initialization(_) => "initialization",
171            Error::Verification(_) => "verification",
172        }
173    }
174
175    /// Check if this error is recoverable (retrying might help)
176    pub const fn is_recoverable(&self) -> bool {
177        matches!(self, Error::Io(_) | Error::Network(_) | Error::Storage(_))
178    }
179
180    /// Check if this error indicates a bug or unexpected condition
181    pub const fn is_internal(&self) -> bool {
182        matches!(self, Error::Internal(_))
183    }
184}