supabase_client_storage/
error.rs1use serde::Deserialize;
2use supabase_client_core::SupabaseError;
3
4#[derive(Debug, Clone, Deserialize)]
6pub struct StorageApiErrorResponse {
7 #[serde(default)]
8 pub error: Option<String>,
9 #[serde(default)]
10 pub message: Option<String>,
11 #[serde(default, rename = "statusCode")]
12 pub status_code: Option<String>,
13}
14
15impl StorageApiErrorResponse {
16 pub fn error_message(&self) -> String {
18 self.message
19 .as_deref()
20 .or(self.error.as_deref())
21 .unwrap_or("Unknown error")
22 .to_string()
23 }
24}
25
26#[derive(Debug, thiserror::Error)]
28pub enum StorageError {
29 #[error("HTTP error: {0}")]
31 Http(#[from] reqwest::Error),
32
33 #[error("Storage API error ({status}): {message}")]
35 Api { status: u16, message: String },
36
37 #[error("Invalid storage configuration: {0}")]
39 InvalidConfig(String),
40
41 #[error("Serialization error: {0}")]
43 Serialization(#[from] serde_json::Error),
44
45 #[error("URL parse error: {0}")]
47 UrlParse(#[from] url::ParseError),
48}
49
50impl From<StorageError> for SupabaseError {
51 fn from(err: StorageError) -> Self {
52 SupabaseError::Storage(err.to_string())
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59
60 #[test]
61 fn error_display_api() {
62 let err = StorageError::Api {
63 status: 404,
64 message: "Not found".into(),
65 };
66 assert_eq!(err.to_string(), "Storage API error (404): Not found");
67 }
68
69 #[test]
70 fn error_display_invalid_config() {
71 let err = StorageError::InvalidConfig("missing url".into());
72 assert_eq!(
73 err.to_string(),
74 "Invalid storage configuration: missing url"
75 );
76 }
77
78 #[test]
79 fn error_converts_to_supabase_error() {
80 let err = StorageError::Api {
81 status: 500,
82 message: "Internal".into(),
83 };
84 let supa: SupabaseError = err.into();
85 match supa {
86 SupabaseError::Storage(msg) => assert!(msg.contains("Internal")),
87 other => panic!("Expected Storage variant, got: {:?}", other),
88 }
89 }
90
91 #[test]
92 fn api_error_response_deserialization() {
93 let json = r#"{"error":"Bucket not found","message":"The resource was not found","statusCode":"404"}"#;
94 let resp: StorageApiErrorResponse = serde_json::from_str(json).unwrap();
95 assert_eq!(resp.error.as_deref(), Some("Bucket not found"));
96 assert_eq!(
97 resp.message.as_deref(),
98 Some("The resource was not found")
99 );
100 assert_eq!(resp.status_code.as_deref(), Some("404"));
101 assert_eq!(resp.error_message(), "The resource was not found");
103 }
104
105 #[test]
106 fn api_error_response_fallback_to_error() {
107 let json = r#"{"error":"Something went wrong"}"#;
108 let resp: StorageApiErrorResponse = serde_json::from_str(json).unwrap();
109 assert_eq!(resp.error_message(), "Something went wrong");
110 }
111
112 #[test]
113 fn api_error_response_unknown() {
114 let json = r#"{}"#;
115 let resp: StorageApiErrorResponse = serde_json::from_str(json).unwrap();
116 assert_eq!(resp.error_message(), "Unknown error");
117 }
118}