qobuz_api_rust/errors.rs
1use thiserror::Error;
2
3/// Custom error types for the Qobuz API Rust library.
4///
5/// This enum represents all possible errors that can occur when using the Qobuz API library.
6/// It includes errors from API responses, network operations, parsing, authentication, and more.
7///
8/// # Examples
9///
10/// ```
11/// use qobuz_api_rust::QobuzApiError;
12///
13/// fn handle_error(error: QobuzApiError) {
14/// match error {
15/// QobuzApiError::ApiErrorResponse { code, message, status } => {
16/// eprintln!("API Error: {} - {} (Status: {})", code, message, status);
17/// }
18/// QobuzApiError::HttpError(e) => {
19/// eprintln!("HTTP Error: {}", e);
20/// }
21/// _ => eprintln!("Other error occurred: {:?}", error),
22/// }
23/// }
24/// ```
25#[derive(Error, Debug)]
26pub enum QobuzApiError {
27 /// Error response from the Qobuz API.
28 ///
29 /// This variant represents an error response received from the Qobuz API itself,
30 /// containing the error code, message, and status returned by the API.
31 ///
32 /// # Fields
33 ///
34 /// * `code` - The error code returned by the API
35 /// * `message` - The error message provided by the API
36 /// * `status` - The status string returned by the API
37 #[error("API Error - Code: {code}, Message: {message}, Status: {status}")]
38 ApiErrorResponse {
39 /// The error code returned by the API
40 code: String,
41 /// The error message provided by the API
42 message: String,
43 /// The status string returned by the API
44 status: String,
45 },
46
47 /// Error when parsing API response.
48 ///
49 /// This variant represents an error that occurs when attempting to parse the
50 /// response from the Qobuz API into a Rust data structure. It includes the
51 /// original content that failed to parse and the underlying parsing error.
52 ///
53 /// # Fields
54 ///
55 /// * `content` - The raw content that failed to parse
56 /// * `source` - The underlying parsing error from `serde_json`
57 #[error("Failed to parse API response: {source}")]
58 ApiResponseParseError {
59 /// The raw content that failed to parse
60 content: String,
61 /// The underlying parsing error from `serde_json`
62 #[source]
63 source: serde_json::Error,
64 },
65
66 /// Error during API initialization.
67 ///
68 /// This variant represents an error that occurs during the initialization
69 /// of the Qobuz API service, such as when failing to extract credentials
70 /// from the web player or when required configuration is missing.
71 ///
72 /// # Fields
73 ///
74 /// * `message` - A description of the initialization error
75 #[error("Qobuz API initialization error: {message}")]
76 QobuzApiInitializationError {
77 /// A description of the initialization error
78 message: String,
79 },
80
81 /// HTTP request error.
82 ///
83 /// This variant wraps errors from the `reqwest` crate that occur during
84 /// HTTP communication with the Qobuz API. This includes connection errors,
85 /// timeout errors, and other network-related issues.
86 #[error("HTTP request error: {0}")]
87 HttpError(#[from] reqwest::Error),
88
89 /// Network/IO error.
90 ///
91 /// This variant wraps errors from the standard library's `std::io::Error`
92 /// that occur during network or file I/O operations, such as when downloading
93 /// tracks or reading local files.
94 #[error("Network/IO error: {0}")]
95 IoError(#[from] std::io::Error),
96
97 /// Lofty library error.
98 ///
99 /// This variant wraps errors from the `lofty` crate that occur during
100 /// audio file metadata operations, such as reading, writing, or modifying tags.
101 /// This includes errors when reading from or saving to audio files.
102 #[error("Lofty metadata error: {0}")]
103 LoftyError(#[from] lofty::error::LoftyError),
104
105 /// URL parsing error.
106 ///
107 /// This variant wraps errors from the `url` crate that occur when parsing
108 /// or constructing URLs for API endpoints.
109 #[error("URL parsing error: {0}")]
110 UrlError(#[from] url::ParseError),
111
112 /// Authentication error.
113 ///
114 /// This variant represents an error that occurs during authentication
115 /// with the Qobuz API, such as invalid credentials or expired tokens.
116 ///
117 /// # Fields
118 ///
119 /// * `message` - A description of the authentication error
120 #[error("Authentication error: {message}")]
121 AuthenticationError {
122 /// A description of the authentication error
123 message: String,
124 },
125
126 /// Error when credentials are missing or invalid.
127 ///
128 /// This variant represents an error that occurs when required credentials
129 /// (app ID, app secret, user token, etc.) are missing, empty, or invalid.
130 #[error("Missing or invalid credentials: {message}")]
131 CredentialsError {
132 /// A description of the credential issue
133 message: String,
134 },
135
136 /// Error when downloading content.
137 ///
138 /// This variant represents an error that occurs during content download operations,
139 /// such as when downloading tracks, images, or other media files.
140 #[error("Download error: {message}")]
141 DownloadError {
142 /// A description of the download issue
143 message: String,
144 },
145
146 /// Error when processing metadata.
147 ///
148 /// This variant represents an error that occurs during metadata extraction,
149 /// embedding, or processing operations.
150 #[error("Metadata processing error: {source}")]
151 MetadataError {
152 /// The underlying error from metadata operations
153 #[source]
154 source: Box<dyn std::error::Error + Send + Sync>,
155 },
156
157 /// Error when a required resource is not found.
158 ///
159 /// This variant represents an error that occurs when a requested resource
160 /// (track, album, artist, etc.) is not found in the Qobuz API.
161 #[error("Resource not found: {resource_type} with ID {resource_id}")]
162 ResourceNotFoundError {
163 /// The type of resource that was not found
164 resource_type: String,
165 /// The ID of the resource that was not found
166 resource_id: String,
167 },
168
169 /// Error when a rate limit is exceeded.
170 ///
171 /// This variant represents an error that occurs when the Qobuz API rate limit
172 /// is exceeded, typically resulting in a 429 HTTP status code.
173 #[error("Rate limit exceeded: {message}")]
174 RateLimitError {
175 /// A description of the rate limit issue
176 message: String,
177 },
178
179 /// Error when an invalid parameter is provided to an API call.
180 ///
181 /// This variant represents an error that occurs when invalid or unsupported
182 /// parameters are passed to an API endpoint.
183 #[error("Invalid parameter: {message}")]
184 InvalidParameterError {
185 /// A description of the invalid parameter
186 message: String,
187 },
188
189 /// Error when the API returns an unexpected response format.
190 ///
191 /// This variant represents an error that occurs when the API returns a response
192 /// that doesn't match the expected format, indicating a potential API change or bug.
193 #[error("Unexpected API response format: {message}")]
194 UnexpectedApiResponseError {
195 /// A description of the unexpected response
196 message: String,
197 },
198}