autopush_common/db/
error.rs

1use actix_web::http::StatusCode;
2
3use thiserror::Error;
4
5#[cfg(feature = "bigtable")]
6use crate::db::bigtable::BigTableError;
7use crate::errors::ReportableError;
8
9pub type DbResult<T> = Result<T, DbError>;
10
11#[derive(Debug, Error)]
12pub enum DbError {
13    #[error("Error while performing (de)serialization: {0}")]
14    Serialization(String),
15
16    #[error("Error deserializing to u64: {0}")]
17    DeserializeU64(String),
18
19    #[error("Error deserializing to String: {0}")]
20    DeserializeString(String),
21
22    #[error("Unable to determine table status")]
23    TableStatusUnknown,
24
25    #[cfg(feature = "bigtable")]
26    #[error("BigTable error: {0}")]
27    BTError(#[from] BigTableError),
28
29    #[error("Connection failure: {0}")]
30    ConnectionError(String),
31
32    #[error("The conditional request failed")]
33    Conditional,
34
35    #[error("Database integrity error: {}", _0)]
36    Integrity(String, Option<String>),
37
38    #[error("Unknown Database Error: {0}")]
39    General(String),
40
41    // Return a 503 error
42    #[error("Process pending, please wait.")]
43    Backoff(String),
44}
45
46impl DbError {
47    pub fn status(&self) -> StatusCode {
48        match self {
49            #[cfg(feature = "bigtable")]
50            Self::BTError(e) => e.status(),
51            Self::Backoff(_) => StatusCode::SERVICE_UNAVAILABLE,
52            _ => StatusCode::INTERNAL_SERVER_ERROR,
53        }
54    }
55}
56
57impl ReportableError for DbError {
58    fn reportable_source(&self) -> Option<&(dyn ReportableError + 'static)> {
59        match &self {
60            #[cfg(feature = "bigtable")]
61            DbError::BTError(e) => Some(e),
62            _ => None,
63        }
64    }
65
66    fn is_sentry_event(&self) -> bool {
67        match &self {
68            #[cfg(feature = "bigtable")]
69            DbError::BTError(e) => e.is_sentry_event(),
70            _ => false,
71        }
72    }
73
74    fn metric_label(&self) -> Option<&'static str> {
75        match &self {
76            #[cfg(feature = "bigtable")]
77            DbError::BTError(e) => e.metric_label(),
78            DbError::Backoff(_) => Some("storage.error.backoff"),
79            _ => None,
80        }
81    }
82
83    fn extras(&self) -> Vec<(&str, String)> {
84        match &self {
85            #[cfg(feature = "bigtable")]
86            DbError::BTError(e) => e.extras(),
87            DbError::Backoff(e) => {
88                vec![("raw", e.to_string())]
89            }
90            DbError::Integrity(_, Some(row)) => vec![("row", row.clone())],
91            _ => vec![],
92        }
93    }
94}