firebase_rs_sdk/storage/
error.rs

1use std::error::Error;
2use std::fmt::{Display, Formatter};
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum StorageErrorCode {
6    Unknown,
7    InvalidUrl,
8    InvalidDefaultBucket,
9    NoDefaultBucket,
10    InvalidArgument,
11    AppDeleted,
12    InvalidRootOperation,
13    InternalError,
14    UnsupportedEnvironment,
15    NoDownloadUrl,
16}
17
18impl StorageErrorCode {
19    pub fn as_str(&self) -> &'static str {
20        match self {
21            StorageErrorCode::Unknown => "storage/unknown",
22            StorageErrorCode::InvalidUrl => "storage/invalid-url",
23            StorageErrorCode::InvalidDefaultBucket => "storage/invalid-default-bucket",
24            StorageErrorCode::NoDefaultBucket => "storage/no-default-bucket",
25            StorageErrorCode::InvalidArgument => "storage/invalid-argument",
26            StorageErrorCode::AppDeleted => "storage/app-deleted",
27            StorageErrorCode::InvalidRootOperation => "storage/invalid-root-operation",
28            StorageErrorCode::InternalError => "storage/internal-error",
29            StorageErrorCode::UnsupportedEnvironment => "storage/unsupported-environment",
30            StorageErrorCode::NoDownloadUrl => "storage/no-download-url",
31        }
32    }
33}
34
35#[derive(Debug, Clone)]
36pub struct StorageError {
37    pub code: StorageErrorCode,
38    message: String,
39    pub status: Option<u16>,
40    pub server_response: Option<String>,
41}
42
43impl StorageError {
44    pub fn new(code: StorageErrorCode, message: impl Into<String>) -> Self {
45        Self {
46            code,
47            message: message.into(),
48            status: None,
49            server_response: None,
50        }
51    }
52
53    pub fn with_status(mut self, status: u16) -> Self {
54        self.status = Some(status);
55        self
56    }
57
58    pub fn with_server_response(mut self, response: impl Into<String>) -> Self {
59        self.server_response = Some(response.into());
60        self
61    }
62
63    pub fn code_str(&self) -> &'static str {
64        self.code.as_str()
65    }
66}
67
68impl Display for StorageError {
69    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
70        if let Some(server) = &self.server_response {
71            write!(f, "{} ({}): {}", self.message, self.code_str(), server)
72        } else {
73            write!(f, "{} ({})", self.message, self.code_str())
74        }
75    }
76}
77
78impl Error for StorageError {}
79
80pub type StorageResult<T> = Result<T, StorageError>;
81
82pub fn unknown_error() -> StorageError {
83    StorageError::new(
84        StorageErrorCode::Unknown,
85        "An unknown error occurred; check the error payload for details.",
86    )
87}
88
89pub fn invalid_url(url: &str) -> StorageError {
90    StorageError::new(
91        StorageErrorCode::InvalidUrl,
92        format!("Invalid storage URL: {url}"),
93    )
94}
95
96pub fn invalid_default_bucket(bucket: &str) -> StorageError {
97    StorageError::new(
98        StorageErrorCode::InvalidDefaultBucket,
99        format!("Invalid default bucket: {bucket}"),
100    )
101}
102
103pub fn no_default_bucket() -> StorageError {
104    StorageError::new(
105        StorageErrorCode::NoDefaultBucket,
106        "No default storage bucket configured on this Firebase app.",
107    )
108}
109
110pub fn invalid_argument(message: impl Into<String>) -> StorageError {
111    StorageError::new(StorageErrorCode::InvalidArgument, message)
112}
113
114pub fn app_deleted() -> StorageError {
115    StorageError::new(
116        StorageErrorCode::AppDeleted,
117        "The Firebase app associated with this Storage instance was deleted.",
118    )
119}
120
121pub fn invalid_root_operation(operation: &str) -> StorageError {
122    StorageError::new(
123        StorageErrorCode::InvalidRootOperation,
124        format!("'{operation}' cannot be performed on the storage root reference."),
125    )
126}
127
128pub fn unsupported_environment(message: impl Into<String>) -> StorageError {
129    StorageError::new(StorageErrorCode::UnsupportedEnvironment, message)
130}
131
132pub fn internal_error(message: impl Into<String>) -> StorageError {
133    StorageError::new(StorageErrorCode::InternalError, message)
134}
135
136pub fn no_download_url() -> StorageError {
137    StorageError::new(
138        StorageErrorCode::NoDownloadUrl,
139        "The requested object does not expose a download URL.",
140    )
141}