autopush_common/db/
error.rs

1use actix_web::http::StatusCode;
2use serde_json::Error as Serde_Error;
3
4use thiserror::Error;
5
6#[cfg(feature = "bigtable")]
7use crate::db::bigtable::BigTableError;
8use crate::errors::ReportableError;
9
10pub type DbResult<T> = Result<T, DbError>;
11
12#[derive(Debug, Error)]
13pub enum DbError {
14    #[error("Error while performing (de)serialization: {0}")]
15    Serialization(String),
16
17    #[error("Error deserializing to u64: {0}")]
18    DeserializeU64(String),
19
20    #[error("Error deserializing to String: {0}")]
21    DeserializeString(String),
22
23    #[error("Unable to determine table status")]
24    TableStatusUnknown,
25
26    #[cfg(feature = "bigtable")]
27    #[error("BigTable error: {0}")]
28    BTError(#[from] BigTableError),
29
30    #[cfg(feature = "redis")]
31    #[error("Redis error {0}")]
32    RedisError(#[from] redis::RedisError),
33
34    #[error("Serde Parse Error {0}")]
35    SerdeError(#[from] Serde_Error),
36
37    #[error("Connection failure: {0}")]
38    ConnectionError(String),
39
40    #[error("The conditional request failed")]
41    Conditional,
42
43    #[error("Database integrity error: {}", _0)]
44    Integrity(String, Option<String>),
45
46    #[error("Unknown Database Error: {0}")]
47    General(String),
48
49    // Return a 503 error
50    #[error("Process pending, please wait.")]
51    Backoff(String),
52
53    #[cfg(feature = "postgres")]
54    #[error("Postgres General Error: {0}")]
55    PgGeneralError(String),
56
57    #[cfg(feature = "postgres")]
58    #[error("Postgres Pool Error: {0}")]
59    PgPoolError(#[from] deadpool::managed::PoolError<tokio_postgres::Error>),
60
61    #[cfg(feature = "postgres")]
62    #[error("Postgres Error: {0}")]
63    PgError(#[from] tokio_postgres::Error),
64
65    #[cfg(feature = "postgres")]
66    #[error("Postgres DB Error: {0}")]
67    PgDbError(String),
68}
69
70impl DbError {
71    pub fn status(&self) -> StatusCode {
72        match self {
73            #[cfg(feature = "bigtable")]
74            Self::BTError(e) => e.status(),
75            Self::Backoff(_) => StatusCode::SERVICE_UNAVAILABLE,
76            _ => StatusCode::INTERNAL_SERVER_ERROR,
77        }
78    }
79}
80
81impl ReportableError for DbError {
82    fn reportable_source(&self) -> Option<&(dyn ReportableError + 'static)> {
83        match &self {
84            #[cfg(feature = "bigtable")]
85            DbError::BTError(e) => Some(e),
86            _ => None,
87        }
88    }
89
90    fn is_sentry_event(&self) -> bool {
91        match &self {
92            #[cfg(feature = "bigtable")]
93            DbError::BTError(e) => e.is_sentry_event(),
94            #[cfg(feature = "postgres")]
95            DbError::PgError(_) => true,
96            #[cfg(feature = "postgres")]
97            DbError::PgPoolError(_) => true,
98            #[cfg(feature = "postgres")]
99            DbError::PgDbError(_) => true,
100            _ => false,
101        }
102    }
103
104    fn metric_label(&self) -> Option<&'static str> {
105        match &self {
106            #[cfg(feature = "bigtable")]
107            DbError::BTError(e) => e.metric_label(),
108            DbError::Backoff(_) => Some("storage.error.backoff"),
109            _ => None,
110        }
111    }
112
113    fn extras(&self) -> Vec<(&str, String)> {
114        match &self {
115            #[cfg(feature = "bigtable")]
116            DbError::BTError(e) => e.extras(),
117            DbError::Backoff(e) => {
118                vec![("raw", e.to_string())]
119            }
120            DbError::Integrity(_, Some(row)) => vec![("row", row.clone())],
121            #[cfg(feature = "postgres")]
122            DbError::PgError(e) => vec![(
123                "error",
124                e.as_db_error()
125                    .map(|e| e.message().to_owned())
126                    .unwrap_or("No error message".to_owned()),
127            )],
128            #[cfg(feature = "postgres")]
129            DbError::PgDbError(v) => vec![("error", v.to_owned())],
130            _ => vec![],
131        }
132    }
133}