1use crate::db::store::StoreError;
2use std::fmt;
3use thiserror::Error as ThisError;
4
5#[derive(Debug, ThisError)]
12#[error("{message}")]
13pub struct InternalError {
14 pub class: ErrorClass,
15 pub origin: ErrorOrigin,
16 pub message: String,
17 pub store: Option<StoreError>,
18}
19
20impl InternalError {
21 pub fn new(class: ErrorClass, origin: ErrorOrigin, message: impl Into<String>) -> Self {
22 let message = message.into();
23 let store = match (class, origin) {
24 (ErrorClass::Corruption, ErrorOrigin::Store) => Some(StoreError::Corrupt {
25 message: message.clone(),
26 }),
27 (ErrorClass::InvariantViolation, ErrorOrigin::Store) => {
28 Some(StoreError::InvariantViolation {
29 message: message.clone(),
30 })
31 }
32 _ => None,
33 };
34 Self {
35 class,
36 origin,
37 message,
38 store,
39 }
40 }
41
42 pub fn store_not_found(key: impl Into<String>) -> Self {
43 let key = key.into();
44 Self {
45 class: ErrorClass::NotFound,
46 origin: ErrorOrigin::Store,
47 message: format!("data key not found: {key}"),
48 store: Some(StoreError::NotFound { key }),
49 }
50 }
51
52 #[must_use]
53 pub const fn is_not_found(&self) -> bool {
54 matches!(self.store, Some(StoreError::NotFound { .. }))
55 }
56
57 #[must_use]
58 pub fn display_with_class(&self) -> String {
59 format!("{}:{}: {}", self.origin, self.class, self.message)
60 }
61}
62
63#[derive(Clone, Copy, Debug, Eq, PartialEq)]
70pub enum ErrorClass {
71 Corruption,
72 NotFound,
73 Internal,
74 Conflict,
75 Unsupported,
76 InvariantViolation,
77}
78
79impl fmt::Display for ErrorClass {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 let label = match self {
82 Self::Corruption => "corruption",
83 Self::NotFound => "not_found",
84 Self::Internal => "internal",
85 Self::Conflict => "conflict",
86 Self::Unsupported => "unsupported",
87 Self::InvariantViolation => "invariant_violation",
88 };
89 write!(f, "{label}")
90 }
91}
92
93#[derive(Clone, Copy, Debug, Eq, PartialEq)]
100pub enum ErrorOrigin {
101 Serialize,
102 Store,
103 Index,
104 Query,
105 Response,
106 Executor,
107 Interface,
108}
109
110impl fmt::Display for ErrorOrigin {
111 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
112 let label = match self {
113 Self::Serialize => "serialize",
114 Self::Store => "store",
115 Self::Index => "index",
116 Self::Query => "query",
117 Self::Response => "response",
118 Self::Executor => "executor",
119 Self::Interface => "interface",
120 };
121 write!(f, "{label}")
122 }
123}