switchgear_components/offer/
error.rs

1use std::borrow::Cow;
2use std::fmt::{Display, Formatter};
3use switchgear_service_api::service::{HasServiceErrorSource, ServiceErrorSource};
4use thiserror::Error;
5
6#[derive(Error, Debug)]
7pub struct OfferStoreError {
8    context: Cow<'static, str>,
9    #[source]
10    source: OfferStoreErrorSourceKind,
11    esource: ServiceErrorSource,
12}
13
14impl Display for OfferStoreError {
15    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
16        write!(
17            f,
18            "OfferStoreError: while {}: {}",
19            self.context.as_ref(),
20            self.source
21        )
22    }
23}
24
25#[derive(Error, Debug)]
26pub enum OfferStoreErrorSourceKind {
27    #[error("database error: {0}")]
28    Database(#[from] sea_orm::DbErr),
29    #[error("resource not found")]
30    NotFound,
31    #[error("serialization failed: {0}")]
32    Serialization(serde_json::Error),
33    #[error("deserialization failed: {0}")]
34    Deserialization(reqwest::Error),
35    #[error("hash conversion failed")]
36    HashConversion,
37    #[error("HTTP request failed: {0}")]
38    Http(reqwest::Error),
39    #[error("HTTP status error: {0}")]
40    HttpStatus(u16),
41    #[error("Internal error: {0}")]
42    Internal(String),
43    #[error("Invalid Input error: {0}")]
44    InvalidInput(String),
45}
46
47impl OfferStoreError {
48    fn new<C: Into<Cow<'static, str>>>(
49        source: OfferStoreErrorSourceKind,
50        esource: ServiceErrorSource,
51        context: C,
52    ) -> Self {
53        Self {
54            context: context.into(),
55            source,
56            esource,
57        }
58    }
59
60    // Convenience constructors for common error types
61    pub fn not_found<C: Into<Cow<'static, str>>>(esource: ServiceErrorSource, context: C) -> Self {
62        Self::new(OfferStoreErrorSourceKind::NotFound, esource, context)
63    }
64
65    pub fn serialization_error<C: Into<Cow<'static, str>>>(
66        esource: ServiceErrorSource,
67        context: C,
68        original_error: serde_json::Error,
69    ) -> Self {
70        Self::new(
71            OfferStoreErrorSourceKind::Serialization(original_error),
72            esource,
73            context,
74        )
75    }
76
77    pub fn hash_conversion_error<C: Into<Cow<'static, str>>>(
78        esource: ServiceErrorSource,
79        context: C,
80    ) -> Self {
81        Self::new(OfferStoreErrorSourceKind::HashConversion, esource, context)
82    }
83
84    pub fn deserialization_error<C: Into<Cow<'static, str>>>(
85        esource: ServiceErrorSource,
86        context: C,
87        original_error: reqwest::Error,
88    ) -> Self {
89        Self::new(
90            OfferStoreErrorSourceKind::Deserialization(original_error),
91            esource,
92            context,
93        )
94    }
95
96    pub fn http_error<C: Into<Cow<'static, str>>>(
97        esource: ServiceErrorSource,
98        context: C,
99        original_error: reqwest::Error,
100    ) -> Self {
101        Self::new(
102            OfferStoreErrorSourceKind::Http(original_error),
103            esource,
104            context,
105        )
106    }
107
108    pub fn http_status_error<C: Into<Cow<'static, str>>>(
109        esource: ServiceErrorSource,
110        context: C,
111        status_code: u16,
112    ) -> Self {
113        Self::new(
114            OfferStoreErrorSourceKind::HttpStatus(status_code),
115            esource,
116            context,
117        )
118    }
119
120    pub fn internal_error<C: Into<Cow<'static, str>>>(
121        esource: ServiceErrorSource,
122        context: C,
123        message: String,
124    ) -> Self {
125        Self::new(
126            OfferStoreErrorSourceKind::Internal(message),
127            esource,
128            context,
129        )
130    }
131
132    pub fn invalid_input_error<C: Into<Cow<'static, str>>>(context: C, message: String) -> Self {
133        Self::new(
134            OfferStoreErrorSourceKind::InvalidInput(message),
135            ServiceErrorSource::Downstream,
136            context,
137        )
138    }
139
140    pub fn from_db<C: Into<Cow<'static, str>>>(
141        esource: ServiceErrorSource,
142        context: C,
143        db_error: sea_orm::DbErr,
144    ) -> Self {
145        Self {
146            source: OfferStoreErrorSourceKind::Database(db_error),
147            esource,
148            context: context.into(),
149        }
150    }
151
152    pub fn context(&self) -> &str {
153        self.context.as_ref()
154    }
155
156    pub fn source(&self) -> &OfferStoreErrorSourceKind {
157        &self.source
158    }
159
160    pub fn esource(&self) -> ServiceErrorSource {
161        self.esource
162    }
163}
164
165impl HasServiceErrorSource for OfferStoreError {
166    fn get_service_error_source(&self) -> ServiceErrorSource {
167        self.esource
168    }
169}