1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
//! # Error Handling and Types
//!
//! This module provides comprehensive error handling utilities for the Supabase client.
//! It defines structured error types, recovery strategies, and debugging utilities
//! to help developers handle failures gracefully.
//!
//! ## 🎯 Error Philosophy
//!
//! The SDK uses a layered error handling approach:
//! - **Structured Errors**: Type-safe error variants for different failure modes
//! - **String Errors**: Simple error messages for end-user operations
//! - **Recovery Guidance**: Clear error messages with actionable solutions
//! - **Debug Support**: Detailed error context for troubleshooting
//!
//! ## 🏗️ Error Types
//!
//! | Error Type | Trigger | Recovery Strategy |
//! |------------|---------|-------------------|
//! | `UnknownError` | Unexpected failures | Check logs, retry operation |
//! | `ApiKeyMissing` | Missing credentials | Set SUPABASE_KEY environment variable |
//! | `AuthorizationFailed` | Invalid/expired key | Verify API key and permissions |
//! | `InvalidQuery` | Malformed requests | Check query syntax and parameters |
//! | `ReqwestError` | Network/HTTP issues | Check connectivity, retry with backoff |
//! | `EnvironmentError` | Missing env vars | Set required environment variables |
//!
//! ## 📖 Usage Examples
//!
//! ### Basic Error Handling
//!
//! ```rust,no_run
//! use supabase_rs::{SupabaseClient, errors::ErrorTypes};
//!
//! # async fn example() -> Result<(), ErrorTypes> {
//! let client = match SupabaseClient::new(
//! std::env::var("SUPABASE_URL").map_err(ErrorTypes::EnvironmentError)?,
//! std::env::var("SUPABASE_KEY").map_err(ErrorTypes::EnvironmentError)?,
//! ) {
//! Ok(client) => client,
//! Err(ErrorTypes::ReqwestError(e)) => {
//! eprintln!("Failed to create HTTP client: {}", e);
//! return Err(ErrorTypes::UnknownError);
//! },
//! Err(e) => return Err(e),
//! };
//! # Ok(())
//! # }
//! ```
//!
//! ### Error Recovery Patterns
//!
//! ```rust,no_run
//! use supabase_rs::SupabaseClient;
//! use serde_json::json;
//! use tokio::time::{sleep, Duration};
//!
//! # async fn example() -> Result<(), String> {
//! # let client = SupabaseClient::new("url".to_string(), "key".to_string()).unwrap();
//! // Retry logic for transient failures
//! async fn insert_with_retry(
//! client: &SupabaseClient,
//! table: &str,
//! data: serde_json::Value,
//! max_retries: u32
//! ) -> Result<String, String> {
//! for attempt in 1..=max_retries {
//! match client.insert(table, data.clone()).await {
//! Ok(id) => return Ok(id),
//! Err(err) if err.contains("timeout") && attempt < max_retries => {
//! println!("Attempt {} failed with timeout, retrying...", attempt);
//! sleep(Duration::from_millis(1000 * attempt as u64)).await;
//! continue;
//! },
//! Err(err) => return Err(err),
//! }
//! }
//! Err("Max retries exceeded".to_string())
//! }
//! # Ok(())
//! # }
//! ```
use Error;
/// Comprehensive error types for Supabase operations.
///
/// This enum provides structured error handling with specific variants for different
/// failure scenarios. Each variant includes descriptive error messages and, where
/// applicable, wraps underlying error types for detailed debugging.
///
/// # Error Categories
///
/// - **Authentication**: `ApiKeyMissing`, `AuthorizationFailed`
/// - **Request**: `InvalidQuery`, `ReqwestError`
/// - **Environment**: `EnvironmentError`
/// - **Generic**: `UnknownError`
///
/// # Examples
///
/// ```rust,no_run
/// use supabase_rs::errors::ErrorTypes;
///
/// fn handle_error(error: ErrorTypes) {
/// match error {
/// ErrorTypes::ApiKeyMissing => {
/// eprintln!("🔑 Set your SUPABASE_KEY environment variable");
/// },
/// ErrorTypes::AuthorizationFailed => {
/// eprintln!("🚫 Check your API key permissions");
/// },
/// ErrorTypes::ReqwestError(e) => {
/// eprintln!("🌐 Network error: {}", e);
/// },
/// ErrorTypes::EnvironmentError(e) => {
/// eprintln!("⚙️ Environment setup error: {}", e);
/// },
/// _ => eprintln!("❌ Unexpected error occurred"),
/// }
/// }
/// ```
/// Type alias for Results using [`ErrorTypes`].
///
/// This provides a convenient shorthand for functions that return structured errors:
/// ```rust,no_run
/// use supabase_rs::errors::Result;
///
/// fn example_operation() -> Result<String> {
/// // Function that might fail with ErrorTypes
/// Ok("success".to_string())
/// }
/// ```
pub type Result<Type> = Result;
/// Creates an unknown error result.
///
/// This function is used internally when an unexpected error occurs that doesn't
/// fit into the other error categories. It returns an `anyhow::Error` for maximum
/// compatibility with error handling chains.
///
/// # Returns
/// Always returns `Err(anyhow::Error)` with a generic unknown error message.
///
/// # Examples
/// ```rust,no_run
/// use supabase_rs::errors::unknown_error;
///
/// # async fn example() {
/// let result = unknown_error().await;
/// assert!(result.is_err());
/// # }
/// ```
pub async
/// Creates an API key missing error result.
///
/// Used when operations fail due to missing or empty API key configuration.
/// Provides actionable guidance for resolving the authentication issue.
///
/// # Returns
/// Always returns `Err(anyhow::Error)` with API key missing guidance.
pub async
/// Creates an authorization failed error result.
///
/// Used when API requests fail due to invalid, expired, or insufficient API key permissions.
/// Indicates that the key exists but lacks the required access level.
///
/// # Returns
/// Always returns `Err(anyhow::Error)` with authorization failure guidance.
pub async
/// Creates an invalid query error result.
///
/// Used when query construction or execution fails due to malformed syntax,
/// invalid parameters, or unsupported operations.
///
/// # Returns
/// Always returns `Err(anyhow::Error)` with query validation guidance.
pub async