1use thiserror::Error;
9
10pub type BoxError = Box<dyn std::error::Error + Send + Sync>;
12
13#[derive(Error, Debug)]
15pub enum EFError {
16 #[error("database connection error: {0}")]
18 Connection(String, #[source] Option<BoxError>),
19
20 #[error("query error: {0}")]
22 Query(String, #[source] Option<BoxError>),
23
24 #[error("entity not found: {0}")]
26 NotFound(String, #[source] Option<BoxError>),
27
28 #[error("model validation error: {0}")]
30 ModelValidation(String, #[source] Option<BoxError>),
31
32 #[error("migration error: {0}")]
34 Migration(String, #[source] Option<BoxError>),
35
36 #[error("provider error: {0}")]
38 Provider(String, #[source] Option<BoxError>),
39
40 #[error("configuration error: {0}")]
42 Configuration(String, #[source] Option<BoxError>),
43
44 #[error("change tracking error: {0}")]
46 ChangeTracking(String, #[source] Option<BoxError>),
47
48 #[error("transaction error: {0}")]
50 Transaction(String, #[source] Option<BoxError>),
51
52 #[error("concurrency conflict: {0}")]
54 ConcurrencyConflict(String, #[source] Option<BoxError>),
55
56 #[error("type conversion error: {0}")]
58 TypeConversion(String, #[source] Option<BoxError>),
59
60 #[error("{0}")]
62 Other(String, #[source] Option<BoxError>),
63}
64
65impl EFError {
66 pub fn connection(msg: impl Into<String>) -> Self {
67 EFError::Connection(msg.into(), None)
68 }
69
70 pub fn query(msg: impl Into<String>) -> Self {
71 EFError::Query(msg.into(), None)
72 }
73
74 pub fn not_found(msg: impl Into<String>) -> Self {
75 EFError::NotFound(msg.into(), None)
76 }
77
78 pub fn model_validation(msg: impl Into<String>) -> Self {
79 EFError::ModelValidation(msg.into(), None)
80 }
81
82 pub fn migration(msg: impl Into<String>) -> Self {
83 EFError::Migration(msg.into(), None)
84 }
85
86 pub fn provider(msg: impl Into<String>) -> Self {
87 EFError::Provider(msg.into(), None)
88 }
89
90 pub fn configuration(msg: impl Into<String>) -> Self {
91 EFError::Configuration(msg.into(), None)
92 }
93
94 pub fn change_tracking(msg: impl Into<String>) -> Self {
95 EFError::ChangeTracking(msg.into(), None)
96 }
97
98 pub fn transaction(msg: impl Into<String>) -> Self {
99 EFError::Transaction(msg.into(), None)
100 }
101
102 pub fn concurrency_conflict(msg: impl Into<String>) -> Self {
103 EFError::ConcurrencyConflict(msg.into(), None)
104 }
105
106 pub fn type_conversion(msg: impl Into<String>) -> Self {
107 EFError::TypeConversion(msg.into(), None)
108 }
109
110 pub fn other(msg: impl Into<String>) -> Self {
111 EFError::Other(msg.into(), None)
112 }
113
114 pub fn with_source(self, source: BoxError) -> Self {
116 match self {
117 EFError::Connection(m, _) => EFError::Connection(m, Some(source)),
118 EFError::Query(m, _) => EFError::Query(m, Some(source)),
119 EFError::NotFound(m, _) => EFError::NotFound(m, Some(source)),
120 EFError::ModelValidation(m, _) => EFError::ModelValidation(m, Some(source)),
121 EFError::Migration(m, _) => EFError::Migration(m, Some(source)),
122 EFError::Provider(m, _) => EFError::Provider(m, Some(source)),
123 EFError::Configuration(m, _) => EFError::Configuration(m, Some(source)),
124 EFError::ChangeTracking(m, _) => EFError::ChangeTracking(m, Some(source)),
125 EFError::Transaction(m, _) => EFError::Transaction(m, Some(source)),
126 EFError::ConcurrencyConflict(m, _) => EFError::ConcurrencyConflict(m, Some(source)),
127 EFError::TypeConversion(m, _) => EFError::TypeConversion(m, Some(source)),
128 EFError::Other(m, _) => EFError::Other(m, Some(source)),
129 }
130 }
131
132 pub fn message(&self) -> &str {
134 match self {
135 EFError::Connection(m, _) => m,
136 EFError::Query(m, _) => m,
137 EFError::NotFound(m, _) => m,
138 EFError::ModelValidation(m, _) => m,
139 EFError::Migration(m, _) => m,
140 EFError::Provider(m, _) => m,
141 EFError::Configuration(m, _) => m,
142 EFError::ChangeTracking(m, _) => m,
143 EFError::Transaction(m, _) => m,
144 EFError::ConcurrencyConflict(m, _) => m,
145 EFError::TypeConversion(m, _) => m,
146 EFError::Other(m, _) => m,
147 }
148 }
149}
150
151pub type EFResult<T> = Result<T, EFError>;