use std::path::PathBuf;
use serde::{Deserialize, Serialize};
use thiserror::Error;
#[derive(Debug, Deserialize, Serialize, Clone)]
pub struct ApiError {
#[serde(default)]
pub status: u16,
#[serde(default)]
pub message: String,
#[serde(rename = "type", alias = "error_type", default)]
pub error_type: Option<String>,
#[serde(default, deserialize_with = "deserialize_code")]
pub code: Option<String>,
}
fn deserialize_code<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = Option::<serde_json::Value>::deserialize(deserializer)?;
Ok(match value {
None | Some(serde_json::Value::Null) => None,
Some(serde_json::Value::String(s)) => Some(s),
Some(other) => Some(other.to_string()),
})
}
impl std::fmt::Display for ApiError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "HTTP {}: {}", self.status, self.message)?;
if let Some(error_type) = &self.error_type {
write!(f, " (type: {error_type})")?;
}
if let Some(code) = &self.code {
write!(f, " (code: {code})")?;
}
Ok(())
}
}
impl std::error::Error for ApiError {}
#[derive(Debug, Deserialize, Clone)]
pub(crate) struct NestedApiError {
pub error: ApiError,
}
#[derive(Debug, Error)]
pub enum OapiError {
#[error("Failed to send request: {0}")]
SendError(#[from] reqwest::Error),
#[error("Response error: {0}")]
ResponseError(String),
#[error("API request failed: {0}")]
ApiError(#[from] ApiError),
#[error("Failed to parse SSE stream: {0}")]
SseParseError(String),
#[error("You cannot post a streaming request in a non-streaming context")]
NonStreamingViolation,
#[error("You cannot post a non-streaming request in a streaming context")]
StreamingViolation,
#[error("Deserialization error:\n{0}\n\nPlease report this error in the project issue.")]
DeserializationError(String),
#[error("Invalid header: {0}")]
InvalidHeader(String),
#[error("File not found at: {0}")]
FileNotFoundError(PathBuf),
#[error("Failed to read file: {0}")]
FileReadError(#[from] std::io::Error),
#[error("Failed to operate on url: {0}")]
UrlError(#[from] url::ParseError),
#[error("Cannot be base: {0}")]
UrlCannotBeBase(String),
}