firebase_rs_sdk/app_check/
errors.rs

1use std::fmt;
2use std::time::{Duration, SystemTimeError};
3
4use crate::app_check::util::format_duration;
5
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub enum AppCheckError {
8    AlreadyInitialized {
9        app_name: String,
10    },
11    UseBeforeActivation {
12        app_name: String,
13    },
14    TokenFetchFailed {
15        message: String,
16    },
17    InvalidConfiguration {
18        message: String,
19    },
20    ProviderError {
21        message: String,
22    },
23    FetchNetworkError {
24        message: String,
25    },
26    FetchParseError {
27        message: String,
28    },
29    FetchStatusError {
30        http_status: u16,
31    },
32    RecaptchaError {
33        message: Option<String>,
34    },
35    InitialThrottle {
36        http_status: u16,
37        retry_after: Duration,
38    },
39    Throttled {
40        http_status: u16,
41        retry_after: Duration,
42    },
43    TokenExpired,
44    Internal(String),
45}
46
47pub type AppCheckResult<T> = Result<T, AppCheckError>;
48
49impl fmt::Display for AppCheckError {
50    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
51        match self {
52            AppCheckError::AlreadyInitialized { app_name } => write!(
53                f,
54                "App Check already initialized for Firebase app '{app_name}' with different options"
55            ),
56            AppCheckError::UseBeforeActivation { app_name } => write!(
57                f,
58                "App Check used before initialize_app_check() for Firebase app '{app_name}'"
59            ),
60            AppCheckError::TokenFetchFailed { message } => {
61                write!(f, "Failed to fetch App Check token: {message}")
62            }
63            AppCheckError::InvalidConfiguration { message } => {
64                write!(f, "Invalid App Check configuration: {message}")
65            }
66            AppCheckError::ProviderError { message } => {
67                write!(f, "App Check provider error: {message}")
68            }
69            AppCheckError::FetchNetworkError { message } => {
70                write!(f, "Failed to reach App Check server: {message}")
71            }
72            AppCheckError::FetchParseError { message } => {
73                write!(f, "Failed to parse App Check response: {message}")
74            }
75            AppCheckError::FetchStatusError { http_status } => {
76                write!(f, "App Check server returned HTTP status {http_status}")
77            }
78            AppCheckError::RecaptchaError { message } => match message {
79                Some(message) => write!(f, "reCAPTCHA error: {message}"),
80                None => write!(f, "reCAPTCHA error"),
81            },
82            AppCheckError::InitialThrottle {
83                http_status,
84                retry_after,
85            } => {
86                let formatted = format_duration(*retry_after);
87                write!(
88                    f,
89                    "Request temporarily blocked after HTTP {http_status}; retry after {formatted}",
90                )
91            }
92            AppCheckError::Throttled {
93                http_status,
94                retry_after,
95            } => {
96                let formatted = format_duration(*retry_after);
97                write!(
98                    f,
99                    "Requests throttled due to previous HTTP {http_status}; retry after {formatted}",
100                )
101            }
102            AppCheckError::TokenExpired => {
103                write!(f, "App Check token has expired")
104            }
105            AppCheckError::Internal(message) => {
106                write!(f, "Internal App Check error: {message}")
107            }
108        }
109    }
110}
111
112impl std::error::Error for AppCheckError {}
113
114impl From<SystemTimeError> for AppCheckError {
115    fn from(error: SystemTimeError) -> Self {
116        AppCheckError::Internal(error.to_string())
117    }
118}