1use crate::error::TransientError;
2use serde::{Deserialize, Serialize};
3use strum_macros::Display;
4use thiserror::Error;
5
6#[cfg(feature = "backend")]
7use actix_web::{body::BoxBody, HttpResponse, ResponseError};
8
9#[allow(missing_docs)]
10#[derive(Debug, Error, Serialize, Deserialize)]
11pub enum ServiceError {
12 #[cfg_attr(feature = "backend", error(transparent))]
13 #[cfg_attr(not(feature = "backend"), error("Internal server error"))]
14 InternalServerError(
15 #[serde(skip)]
16 #[from]
17 TransientError<anyhow::Error>,
18 ),
19 #[error("{0}")]
20 DisabledService(ServiceKindError),
21 #[error("Forbidden")]
22 Forbidden,
23 #[error("Resource not found")]
24 ResourceNotFound,
25}
26
27#[cfg(feature = "backend")]
28impl ResponseError for ServiceError {
29 fn status_code(&self) -> http::StatusCode {
30 match self {
31 Self::InternalServerError { .. } => http::StatusCode::INTERNAL_SERVER_ERROR,
32 Self::DisabledService(_) => http::StatusCode::NOT_IMPLEMENTED,
33 Self::Forbidden => http::StatusCode::FORBIDDEN,
34 Self::ResourceNotFound => http::StatusCode::NOT_FOUND,
35 }
36 }
37
38 fn error_response(&self) -> HttpResponse<BoxBody> {
39 HttpResponse::build(self.status_code()).json(self)
40 }
41}
42
43impl From<anyhow::Error> for ServiceError {
44 fn from(e: anyhow::Error) -> Self {
45 Self::InternalServerError(e.into())
46 }
47}
48
49#[allow(missing_docs)]
50#[derive(Debug, Copy, Clone, Display, Serialize, Deserialize)]
51pub enum ServiceKindError {
52 #[strum(serialize = "Algolia")]
53 Algolia,
54 #[strum(serialize = "S3")]
55 S3,
56 #[strum(serialize = "Google Cloud Storage")]
57 GoogleCloudStorage,
58 #[strum(serialize = "Google Cloud EventArc")]
59 GoogleCloudEventArc,
60 #[strum(serialize = "Google OAuth")]
61 GoogleOAuth,
62 #[strum(serialize = "Google Cloud Access Key Store")]
63 GoogleCloudAccessKeyStore,
64 #[strum(serialize = "Sendgrid Mail")]
65 Mail,
66 #[strum(serialize = "Firebase Cloud Messaging")]
67 FirebaseCloudMessaging,
68 #[strum(serialize = "Media Upload Cleaner")]
69 UploadCleaner,
70 #[strum(serialize = "Google Translate")]
71 GoogleTranslate,
72 #[strum(serialize = "Stripe")]
73 Stripe,
74}
75
76#[cfg(feature = "backend")]
77impl ResponseError for ServiceKindError {
78 fn status_code(&self) -> http::StatusCode {
79 http::StatusCode::NOT_IMPLEMENTED
80 }
81
82 fn error_response(&self) -> HttpResponse<BoxBody> {
83 HttpResponse::build(self.status_code()).json(self)
84 }
85}