fcm_device_group/
error.rs1use std::fmt::Display;
4
5use reqwest::{StatusCode, header::InvalidHeaderValue};
6use serde::{Deserialize, de::DeserializeOwned};
7use thiserror::Error;
8
9#[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#[derive(Debug, Error)]
29pub enum FCMDeviceGroupsRequestError<E: FCMDeviceGroupError> {
30 #[error("Error Making HTTP Request with FCM")]
32 HttpError(#[from] reqwest::Error),
33 #[error("Error Getting Auth Token")]
35 GetTokenError(Box<dyn std::error::Error + Send + Sync>),
36 #[error("Bad Request")]
38 BadRequestError(#[from] E),
39}
40
41impl<E: FCMDeviceGroupError> FCMDeviceGroupsRequestError<E> {
42 pub(crate) async fn json_response<T: DeserializeOwned>(
43 resp: reqwest::Response,
44 ) -> Result<T, Self> {
45 match resp.error_for_status_ref() {
46 Ok(_) => Ok(resp.json::<T>().await?),
47 Err(e) => match e.status().unwrap() {
48 StatusCode::BAD_REQUEST => {
49 let string_error = resp.json::<FCMDeviceGroupsBadRequest>().await?;
50 Err(match E::from_error_str(string_error) {
51 Some(custom_error) => Self::BadRequestError(custom_error),
52 None => Self::HttpError(e),
53 })
54 }
55 _ => Err(Self::HttpError(e)),
56 },
57 }
58 }
59}
60
61#[derive(Debug, Deserialize, Error)]
63pub struct FCMDeviceGroupsBadRequest {
64 pub error: String,
66}
67
68impl FCMDeviceGroupError for FCMDeviceGroupsBadRequest {
69 fn from_error_str(error: FCMDeviceGroupsBadRequest) -> Option<Self> {
70 Some(error)
71 }
72}
73
74impl Display for FCMDeviceGroupsBadRequest {
75 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
76 write!(f, "{}", self.error)
77 }
78}
79
80#[allow(missing_docs)]
81pub mod operation_errors {
82 use thiserror::Error;
85
86 use crate::error::FCMDeviceGroupError;
87
88 const ALREADY_EXISTS_MESSAGE: &str = "notification_key already exists";
89 const NO_REGISTRATION_ID_MESSAGE: &str = "no valid registration ids";
90 const KEY_NAME_AND_KEY_DONT_MATCH: &str =
91 "notification_key_name doesn't match the group name of the notification_key";
92 const KEY_NOT_FOUND: &str = "notification_key not found";
93
94 pub type OperationResult<T, E> = Result<T, super::FCMDeviceGroupsRequestError<E>>;
95
96 #[derive(Debug, Error)]
97 pub enum CreateGroupError {
98 #[error("{}", ALREADY_EXISTS_MESSAGE)]
99 AlreadyExists,
100 #[error("{}", NO_REGISTRATION_ID_MESSAGE)]
101 NoValidRegistrationIds,
102 }
103
104 impl FCMDeviceGroupError for CreateGroupError {
105 fn from_error_str(error: super::FCMDeviceGroupsBadRequest) -> Option<Self> {
106 match error.error.as_str() {
107 ALREADY_EXISTS_MESSAGE => Some(Self::AlreadyExists),
108 NO_REGISTRATION_ID_MESSAGE => Some(Self::NoValidRegistrationIds),
109 _ => None,
110 }
111 }
112 }
113
114 #[derive(Debug, Error)]
115 pub enum ChangeGroupMembersError {
116 #[error("{}", NO_REGISTRATION_ID_MESSAGE)]
117 NoValidRegistrationIds,
118 #[error("{KEY_NAME_AND_KEY_DONT_MATCH}")]
119 KeyNameAndKeyDontMatch,
120 #[error("{KEY_NOT_FOUND}")]
121 KeyNotFound,
122 }
123
124 impl FCMDeviceGroupError for ChangeGroupMembersError {
125 fn from_error_str(error: super::FCMDeviceGroupsBadRequest) -> Option<Self> {
126 match error.error.as_str() {
127 NO_REGISTRATION_ID_MESSAGE => Some(Self::NoValidRegistrationIds),
128 KEY_NAME_AND_KEY_DONT_MATCH => Some(Self::KeyNameAndKeyDontMatch),
129 KEY_NOT_FOUND => Some(Self::KeyNotFound),
130 _ => None,
131 }
132 }
133 }
134
135 #[derive(Debug, Error)]
136 pub enum GetKeyError {
137 #[error("{KEY_NOT_FOUND}")]
138 KeyNotFound,
139 }
140 impl FCMDeviceGroupError for GetKeyError {
141 fn from_error_str(error: super::FCMDeviceGroupsBadRequest) -> Option<Self> {
142 match error.error.as_str() {
143 KEY_NOT_FOUND => Some(Self::KeyNotFound),
144 _ => None,
145 }
146 }
147 }
148}
149
150#[derive(Debug, Error)]
151pub(crate) enum RawError {
152 #[error("Error Making HTTP Request with FCM")]
153 HttpError(#[from] reqwest::Error),
154 #[error("Error Getting Auth Token")]
156 GetTokenError(Box<dyn std::error::Error + Send + Sync>),
157}
158
159impl<E: FCMDeviceGroupError> From<RawError> for FCMDeviceGroupsRequestError<E> {
160 fn from(raw: RawError) -> Self {
161 match raw {
162 RawError::HttpError(error) => Self::HttpError(error),
163 RawError::GetTokenError(error) => Self::GetTokenError(error),
164 }
165 }
166}