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>;