1use std::borrow::Cow;
4use std::error::Error as StdError;
5
6use thiserror::Error;
7
8use crate::capability::StorageCapability;
9
10#[derive(Debug, Error)]
12pub enum StorageError {
13 #[error("{capability:?} resource not found: {resource} ({key})")]
14 NotFound {
15 capability: StorageCapability,
16 resource: &'static str,
17 key: String,
18 },
19
20 #[error("{capability:?} resource already exists: {resource} ({key})")]
21 AlreadyExists {
22 capability: StorageCapability,
23 resource: &'static str,
24 key: String,
25 },
26
27 #[error("conflict in {capability:?} during {operation}: {message}")]
28 Conflict {
29 capability: StorageCapability,
30 operation: Cow<'static, str>,
31 message: String,
32 },
33
34 #[error("invalid input for {capability:?} during {operation}: {message}")]
35 InvalidInput {
36 capability: StorageCapability,
37 operation: Cow<'static, str>,
38 message: String,
39 },
40
41 #[error("unsupported operation for {capability:?}: {operation} ({message})")]
42 Unsupported {
43 capability: StorageCapability,
44 operation: Cow<'static, str>,
45 message: String,
46 },
47
48 #[error("pool failure during {operation}: {message}")]
49 Pool {
50 operation: Cow<'static, str>,
51 message: String,
52 },
53
54 #[error("timeout during {operation}")]
55 Timeout { operation: Cow<'static, str> },
56
57 #[error("sql transaction failure during {operation}: {message}")]
58 Transaction {
59 operation: Cow<'static, str>,
60 message: String,
61 },
62
63 #[error("serialization failure in {capability:?}: {message}")]
64 Serialization {
65 capability: StorageCapability,
66 message: String,
67 },
68
69 #[error("index maintenance failure in {capability:?}: {message}")]
70 IndexMaintenance {
71 capability: StorageCapability,
72 message: String,
73 },
74
75 #[error("backend driver error in {capability:?} during {operation}: {source}")]
76 Driver {
77 capability: StorageCapability,
78 operation: Cow<'static, str>,
79 #[source]
80 source: Box<dyn StdError + Send + Sync>,
81 },
82}
83
84impl StorageError {
85 pub fn driver(
86 capability: StorageCapability,
87 operation: impl Into<Cow<'static, str>>,
88 source: impl StdError + Send + Sync + 'static,
89 ) -> Self {
90 Self::Driver {
91 capability,
92 operation: operation.into(),
93 source: Box::new(source),
94 }
95 }
96
97 pub fn capability(&self) -> Option<StorageCapability> {
98 match self {
99 Self::NotFound { capability, .. }
100 | Self::AlreadyExists { capability, .. }
101 | Self::Conflict { capability, .. }
102 | Self::InvalidInput { capability, .. }
103 | Self::Unsupported { capability, .. }
104 | Self::Serialization { capability, .. }
105 | Self::IndexMaintenance { capability, .. }
106 | Self::Driver { capability, .. } => Some(*capability),
107 Self::Pool { .. } | Self::Timeout { .. } | Self::Transaction { .. } => None,
108 }
109 }
110
111 pub fn is_retryable(&self) -> bool {
112 matches!(
113 self,
114 Self::Pool { .. } | Self::Timeout { .. } | Self::Transaction { .. }
115 )
116 }
117}