Skip to main content

dactyl_db/
error.rs

1//! Errors returned by the Dactyl driver.
2
3use thiserror::Error;
4
5/// Coarse operational categories stable enough for callers to branch on.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum AdapterErrorKind {
8    Busy,
9    Locked,
10    Timeout,
11    Constraint,
12    Conflict,
13    Query,
14    InvalidOperation,
15    ReadOnly,
16    Capability,
17    Value,
18    Storage,
19    Transport,
20    Protocol,
21    Unavailable,
22    Cancellation,
23    Unknown,
24}
25
26/// The backend-neutral public error surface.
27#[derive(Debug, Error)]
28pub enum DactylError {
29    #[error("configuration error: {0}")]
30    Config(String),
31
32    #[error("adapter error ({kind:?}): {message}")]
33    Adapter {
34        kind: AdapterErrorKind,
35        message: String,
36    },
37
38    #[error("unsupported datastore operation: {0}")]
39    UnsupportedOperation(String),
40
41    #[error("column not found: {0}")]
42    ColumnNotFound(String),
43
44    #[error("conversion error: {0}")]
45    Conversion(String),
46}
47
48impl DactylError {
49    #[allow(dead_code)]
50    pub(crate) fn adapter(kind: AdapterErrorKind, message: impl Into<String>) -> Self {
51        Self::Adapter {
52            kind,
53            message: message.into(),
54        }
55    }
56
57    pub fn adapter_kind(&self) -> Option<AdapterErrorKind> {
58        match self {
59            Self::Adapter { kind, .. } => Some(*kind),
60            _ => None,
61        }
62    }
63
64    pub fn is_retryable(&self) -> bool {
65        matches!(
66            self.adapter_kind(),
67            Some(AdapterErrorKind::Busy | AdapterErrorKind::Locked | AdapterErrorKind::Timeout)
68        )
69    }
70}