dojo_cli/
utils.rs

1use reqwest::Response;
2use serde_json::Value;
3
4pub struct ApiResponseHandler;
5
6impl ApiResponseHandler {
7    /// Handles API responses and detects common error conditions including expired tokens
8    pub async fn handle_response(response: Response) -> Result<Value, Box<dyn std::error::Error>> {
9        let status = response.status();
10        let response_text = response.text().await?;
11
12        // Try to parse as JSON first
13        let json_response: Result<Value, _> = serde_json::from_str(&response_text);
14
15        match json_response {
16            Ok(json) => {
17                // Check for specific error conditions in the JSON response
18                if let Some(error_msg) = json["error"].as_str() {
19                    // Check for expired token error
20                    if error_msg.contains("expired") || error_msg.contains("Token has expired") {
21                        return Err("❌ Your API token has expired. Please run 'dojo-cli config' to update your token.".into());
22                    }
23
24                    // Check for unauthorized/authentication errors
25                    if status.as_u16() == 401 || status.as_u16() == 403 {
26                        if error_msg.contains("unauthorized")
27                            || error_msg.contains("forbidden")
28                            || error_msg.contains("invalid")
29                            || error_msg.contains("Invalid token")
30                        {
31                            return Err("❌ Authentication failed. Please run 'dojo-cli config' to update your API token.".into());
32                        }
33                    }
34
35                    return Err(format!("❌ API Error: {}", error_msg).into());
36                }
37
38                // If no error field, return the JSON response
39                Ok(json)
40            }
41            Err(_) => {
42                // If not JSON, check status code for common HTTP errors
43                match status.as_u16() {
44                    401 => Err("❌ Unauthorized: Your API token is invalid or expired. Generate a new token using the Bitcoin Dojo website, and run 'dojo-cli config' to update your token.".into()),
45                    403 => Err("❌ Forbidden: Your API token doesn't have permission for this operation. Please run 'dojo-cli config' to update your token.".into()),
46                    404 => Err("❌ Not Found: The requested resource was not found.".into()),
47                    429 => Err("❌ Rate Limited: Too many requests. Please try again later.".into()),
48                    500..=599 => Err("❌ Server Error: The Bitcoin Dojo service is experiencing issues. Please try again later.".into()),
49                    _ => Err(format!("❌ API request failed with status {}: {}", status, response_text).into()),
50                }
51            }
52        }
53    }
54}