fcm_device_group/
error.rs

1//! Errors returns by the FCM device group APIs
2//!
3use std::fmt::Display;
4
5use reqwest::{StatusCode, header::InvalidHeaderValue};
6use serde::{Deserialize, de::DeserializeOwned};
7use thiserror::Error;
8
9/// Error when creating FCM Device Groups Client
10#[derive(Debug, Error)]
11pub enum FCMDeviceGroupClientCreationError {
12    #[allow(missing_docs)]
13    #[error("Error Making Authorization Header")]
14    InvalidHeaderValue(#[from] InvalidHeaderValue),
15    #[allow(missing_docs)]
16    #[error("Build Client Error")]
17    ClientBuild(#[from] reqwest::Error),
18}
19
20#[allow(missing_docs)]
21pub trait FCMDeviceGroupError: std::error::Error + Sized {
22    fn from_error_str(error: FCMDeviceGroupsBadRequest) -> Option<Self>;
23}
24
25/// Error When Making an FCM Device Groups Request
26///
27/// E is a generic parameter for a request specific error
28#[derive(Debug, Error)]
29pub enum FCMDeviceGroupsRequestError<E: FCMDeviceGroupError> {
30    /// Error http error
31    #[error("Error Making HTTP Request with FCM")]
32    HttpError(#[from] reqwest::Error),
33    /// Parsed Bad Request Error
34    #[error("Bad Request")]
35    BadRequestError(#[from] E),
36}
37
38impl<E: FCMDeviceGroupError> FCMDeviceGroupsRequestError<E> {
39    pub(crate) async fn json_response<T: DeserializeOwned>(
40        resp: reqwest::Response,
41    ) -> Result<T, Self> {
42        match resp.error_for_status_ref() {
43            Ok(_) => Ok(resp.json::<T>().await?),
44            Err(e) => match e.status().unwrap() {
45                StatusCode::BAD_REQUEST => {
46                    let string_error = resp.json::<FCMDeviceGroupsBadRequest>().await?;
47                    Err(match E::from_error_str(string_error) {
48                        Some(custom_error) => Self::BadRequestError(custom_error),
49                        None => Self::HttpError(e),
50                    })
51                }
52                _ => Err(Self::HttpError(e)),
53            },
54        }
55    }
56}
57
58/// Bad Request Error from FCM
59#[derive(Debug, Deserialize, Error)]
60pub struct FCMDeviceGroupsBadRequest {
61    /// Bad request message body from fcm
62    pub error: String,
63}
64
65impl FCMDeviceGroupError for FCMDeviceGroupsBadRequest {
66    fn from_error_str(error: FCMDeviceGroupsBadRequest) -> Option<Self> {
67        Some(error)
68    }
69}
70
71impl Display for FCMDeviceGroupsBadRequest {
72    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73        write!(f, "{}", self.error)
74    }
75}
76
77#[allow(missing_docs)]
78pub mod operation_errors {
79    //! Operation Specific Errors
80
81    use thiserror::Error;
82
83    use crate::error::FCMDeviceGroupError;
84
85    const ALREADY_EXISTS_MESSAGE: &str = "notification_key already exists";
86    const NO_REGISTRATION_ID_MESSAGE: &str = "no valid registration ids";
87    const KEY_NAME_AND_KEY_DONT_MATCH: &str =
88        "notification_key_name doesn't match the group name of the notification_key";
89    const KEY_NOT_FOUND: &str = "notification_key not found";
90
91    pub type OperationResult<T, E> = Result<T, super::FCMDeviceGroupsRequestError<E>>;
92
93    #[derive(Debug, Error)]
94    pub enum CreateGroupError {
95        #[error("{}", ALREADY_EXISTS_MESSAGE)]
96        AlreadyExists,
97        #[error("{}", NO_REGISTRATION_ID_MESSAGE)]
98        NoValidRegistrationIds,
99    }
100
101    impl FCMDeviceGroupError for CreateGroupError {
102        fn from_error_str(error: super::FCMDeviceGroupsBadRequest) -> Option<Self> {
103            match error.error.as_str() {
104                ALREADY_EXISTS_MESSAGE => Some(Self::AlreadyExists),
105                NO_REGISTRATION_ID_MESSAGE => Some(Self::NoValidRegistrationIds),
106                _ => None,
107            }
108        }
109    }
110
111    #[derive(Debug, Error)]
112    pub enum ChangeGroupMembersError {
113        #[error("{}", NO_REGISTRATION_ID_MESSAGE)]
114        NoValidRegistrationIds,
115        #[error("{KEY_NAME_AND_KEY_DONT_MATCH}")]
116        KeyNameAndKeyDontMatch,
117        #[error("{KEY_NOT_FOUND}")]
118        KeyNotFound,
119    }
120
121    impl FCMDeviceGroupError for ChangeGroupMembersError {
122        fn from_error_str(error: super::FCMDeviceGroupsBadRequest) -> Option<Self> {
123            match error.error.as_str() {
124                NO_REGISTRATION_ID_MESSAGE => Some(Self::NoValidRegistrationIds),
125                KEY_NAME_AND_KEY_DONT_MATCH => Some(Self::KeyNameAndKeyDontMatch),
126                KEY_NOT_FOUND => Some(Self::KeyNotFound),
127                _ => None,
128            }
129        }
130    }
131
132    #[derive(Debug, Error)]
133    pub enum GetKeyError {
134        #[error("{KEY_NOT_FOUND}")]
135        KeyNotFound,
136    }
137    impl FCMDeviceGroupError for GetKeyError {
138        fn from_error_str(error: super::FCMDeviceGroupsBadRequest) -> Option<Self> {
139            match error.error.as_str() {
140                KEY_NOT_FOUND => Some(Self::KeyNotFound),
141                _ => None,
142            }
143        }
144    }
145}