serp_sdk/
error.rs

1use thiserror::Error;
2
3/// Comprehensive error types for SerpAPI SDK operations.
4///
5/// This enum covers all possible error conditions that can occur when using the SDK,
6/// from configuration issues to network problems and API-specific errors.
7///
8/// # Examples
9///
10/// ```rust
11/// use serp_sdk::{SerpClient, SerpError};
12///
13/// // Handle specific error types
14/// match SerpClient::builder().build() {
15///     Ok(client) => println!("Client created successfully"),
16///     Err(SerpError::MissingApiKey) => {
17///         println!("Please set SERP_API_KEY environment variable");
18///     }
19///     Err(e) => println!("Other error: {}", e),
20/// }
21/// ```
22#[derive(Debug, Error)]
23#[non_exhaustive]
24pub enum SerpError {
25    /// API key not provided via builder or environment variable.
26    ///
27    /// Set the API key using [`SerpClientBuilder::api_key`] or the `SERP_API_KEY` environment variable.
28    ///
29    /// [`SerpClientBuilder::api_key`]: crate::client::SerpClientBuilder::api_key
30    #[error("API key not provided")]
31    MissingApiKey,
32
33    /// Error during HTTP client construction.
34    ///
35    /// This typically indicates an issue with the underlying HTTP client configuration,
36    /// such as invalid TLS settings or proxy configuration.
37    #[error("Client builder error: {0}")]
38    ClientBuilder(String),
39
40    /// HTTP request failed.
41    ///
42    /// This wraps underlying [`reqwest::Error`] and can indicate network connectivity issues,
43    /// DNS resolution failures, or connection timeouts.
44    #[error("Request failed: {0}")]
45    RequestFailed(#[from] reqwest::Error),
46
47    /// Response could not be parsed or has invalid format.
48    ///
49    /// This occurs when the API returns a response that doesn't match the expected JSON structure,
50    /// which might indicate API changes or corrupted responses.
51    #[error("Invalid response format: {0}")]
52    InvalidResponse(String),
53
54    /// Rate limit exceeded, with retry-after duration.
55    ///
56    /// SerpAPI has rate limits. When exceeded, this error includes the number of seconds
57    /// to wait before retrying. The SDK's retry logic handles this automatically.
58    #[error("Rate limit exceeded: retry after {retry_after} seconds")]
59    RateLimited {
60        /// Number of seconds to wait before retrying
61        retry_after: u64,
62    },
63
64    /// API returned an error response.
65    ///
66    /// This represents HTTP error status codes (4xx, 5xx) returned by the SerpAPI service,
67    /// such as authentication failures or server errors.
68    #[error("API error: {code} - {message}")]
69    ApiError {
70        /// HTTP status code
71        code: u16,
72        /// Error message from the API
73        message: String,
74    },
75
76    /// JSON serialization/deserialization error.
77    ///
78    /// This wraps [`serde_json::Error`] and occurs when request parameters cannot be
79    /// serialized or response data cannot be deserialized.
80    #[error("Serialization error: {0}")]
81    Serialization(#[from] serde_json::Error),
82
83    /// URL encoding error.
84    ///
85    /// This occurs when query parameters cannot be properly URL-encoded,
86    /// typically due to invalid characters in parameter values.
87    #[error("URL encoding error: {0}")]
88    UrlEncoding(#[from] serde_urlencoded::ser::Error),
89
90    /// Invalid query parameter.
91    ///
92    /// This is thrown when query parameters fail validation, such as
93    /// setting a limit outside the valid range (1-100).
94    #[error("Invalid query parameter: {0}")]
95    InvalidParameter(String),
96
97    /// Timeout during request execution.
98    ///
99    /// The request exceeded the configured timeout duration.
100    /// Adjust the timeout using [`SerpClientBuilder::timeout`].
101    ///
102    /// [`SerpClientBuilder::timeout`]: crate::client::SerpClientBuilder::timeout
103    #[error("Request timeout")]
104    Timeout,
105
106    /// Network connectivity issues.
107    ///
108    /// This represents lower-level network problems that don't fit into
109    /// other categories, such as proxy failures or DNS issues.
110    #[error("Network error: {0}")]
111    Network(String),
112}
113
114/// Result type alias for SerpAPI operations.
115///
116/// This is a convenience type alias that uses [`SerpError`] as the error type.
117/// Most functions in this crate return this type.
118///
119/// # Examples
120///
121/// ```rust
122/// use serp_sdk::{SerpResult, SerpClient};
123///
124/// fn create_client() -> SerpResult<SerpClient> {
125///     SerpClient::builder()
126///         .api_key("test-key")
127///         .build()
128/// }
129/// ```
130pub type SerpResult<T> = Result<T, SerpError>;