1use thiserror::Error;
7use std::io;
8use uuid::Uuid;
9
10#[derive(Error, Debug)]
23pub enum StorageError {
24 #[error("I/O error: {0}")]
26 Io(#[from] io::Error),
27
28 #[error("Data integrity error: CRC mismatch at offset {offset}, expected {expected:x}, got {actual:x}")]
30 CrcMismatch {
31 offset: u64,
32 expected: u32,
33 actual: u32,
34 },
35
36 #[error("Invalid data format: {message}")]
38 InvalidFormat { message: String },
39
40 #[error("Segment not found: {segment_id}")]
42 SegmentNotFound { segment_id: Uuid },
43
44 #[error("Offset out of range: {offset} is beyond available data")]
46 OffsetOutOfRange { offset: u64 },
47
48 #[error("Configuration error: {message}")]
50 Configuration { message: String },
51
52 #[error("Insufficient disk space: need {required} bytes, available {available} bytes")]
54 InsufficientSpace {
55 required: u64,
56 available: u64,
57 },
58
59 #[error("Synchronization error: {message}")]
61 Synchronization { message: String },
62
63 #[error("Serialization error: {0}")]
65 Serialization(#[from] bincode::Error),
66
67 #[error("Internal error: {message}")]
69 Internal { message: String },
70}
71
72impl StorageError {
73 pub fn configuration(message: impl Into<String>) -> Self {
75 Self::Configuration {
76 message: message.into(),
77 }
78 }
79
80 pub fn invalid_format(message: impl Into<String>) -> Self {
82 Self::InvalidFormat {
83 message: message.into(),
84 }
85 }
86
87 pub fn internal(message: impl Into<String>) -> Self {
89 Self::Internal {
90 message: message.into(),
91 }
92 }
93
94 pub fn synchronization(message: impl Into<String>) -> Self {
96 Self::Synchronization {
97 message: message.into(),
98 }
99 }
100
101 pub fn is_retryable(&self) -> bool {
110 match self {
111 Self::Io(_) => true,
112 Self::InsufficientSpace { .. } => false,
113 Self::CrcMismatch { .. } => false,
114 Self::InvalidFormat { .. } => false,
115 Self::SegmentNotFound { .. } => false,
116 Self::OffsetOutOfRange { .. } => false,
117 Self::Configuration { .. } => false,
118 Self::Synchronization { .. } => true,
119 Self::Serialization(_) => false,
120 Self::Internal { .. } => false,
121 }
122 }
123
124 pub fn severity(&self) -> ErrorSeverity {
131 match self {
132 Self::CrcMismatch { .. } => ErrorSeverity::High,
133 Self::InsufficientSpace { .. } => ErrorSeverity::High,
134 Self::Internal { .. } => ErrorSeverity::High,
135 Self::InvalidFormat { .. } => ErrorSeverity::Medium,
136 Self::SegmentNotFound { .. } => ErrorSeverity::Medium,
137 Self::Configuration { .. } => ErrorSeverity::Medium,
138 Self::Io(_) => ErrorSeverity::Low,
139 Self::OffsetOutOfRange { .. } => ErrorSeverity::Low,
140 Self::Synchronization { .. } => ErrorSeverity::Low,
141 Self::Serialization(_) => ErrorSeverity::Low,
142 }
143 }
144}
145
146#[derive(Debug, Clone, Copy, PartialEq, Eq)]
148pub enum ErrorSeverity {
149 High,
151 Medium,
153 Low,
155}
156
157pub type StorageResult<T> = Result<T, StorageError>;