nomi_api_client/
errors.rs

1use reqwest::StatusCode;
2use serde::Deserialize;
3use serde_json::Error as SerdeError;
4use thiserror::Error;
5
6/// Represents an API error response.
7#[derive(Debug, Deserialize)]
8pub struct APIErrorResponse {
9    pub error: APIError,
10}
11
12/// Describes the API error type.
13#[derive(Debug, Deserialize)]
14pub struct APIError {
15    #[serde(rename = "type")]
16    pub error_type: String,
17}
18
19/// Represents different error cases for the Nomi AI client.
20#[derive(Debug, Error)]
21pub enum NomiError {
22    /// HTTP request error (e.g., network failure).
23    #[error("HTTP request failed: {0}")]
24    ReqwestError(#[from] reqwest::Error),
25
26    /// API returned an error response.
27    #[error("API error: {0}")]
28    APIError(String),
29
30    /// JSON deserialization error.
31    #[error("Failed to parse response: {0}")]
32    JSONError(#[from] SerdeError),
33
34    /// Unexpected response format.
35    #[error("Unexpected response format")]
36    UnexpectedFormat,
37}
38
39impl NomiError {
40    /// Attempts to parse an API error from a response.
41    pub async fn from_response(response: reqwest::Response) -> Self {
42        match response.status() {
43            StatusCode::UNAUTHORIZED
44            | StatusCode::FORBIDDEN
45            | StatusCode::NOT_FOUND
46            | StatusCode::BAD_REQUEST => {
47                if let Ok(api_error) = response.json::<APIErrorResponse>().await {
48                    NomiError::APIError(api_error.error.error_type)
49                } else {
50                    NomiError::UnexpectedFormat
51                }
52            }
53            _ => NomiError::ReqwestError(response.error_for_status().unwrap_err()),
54        }
55    }
56}