1use thiserror::Error;
4
5#[derive(Debug, Error)]
6pub enum Error {
7 #[error("Database error: {0}")]
8 Database(String),
9
10 #[error("Not found: {0}")]
11 NotFound(String),
12
13 #[error("Validation error: {0}")]
14 Validation(String),
15
16 #[error("Privacy policy violation: {0}")]
17 Privacy(String),
18
19 #[error("Internal error: {0}")]
20 Internal(String),
21
22 #[error("Serialization error: {0}")]
23 Serialization(String),
24
25 #[error("Pending deletion: {0}")]
26 PendingDeletion(String),
27
28 #[error("Identity error: {0}")]
29 Identity(String),
30}
31
32impl From<serde_json::Error> for Error {
33 fn from(e: serde_json::Error) -> Self {
34 Error::Serialization(e.to_string())
35 }
36}
37
38impl Error {
39 pub fn is_retryable_transaction_contention(&self) -> bool {
41 match self {
42 Error::Database(msg) => {
43 let s = msg.to_lowercase();
44 s.contains("read or write conflict")
45 || s.contains("can be retried")
46 || (s.contains("failed transaction") && s.contains("conflict"))
47 }
48 _ => false,
49 }
50 }
51}
52
53impl From<&str> for Error {
54 fn from(s: &str) -> Self {
55 Error::Validation(s.to_string())
56 }
57}
58
59pub type Result<T> = std::result::Result<T, Error>;