1use serde::{Deserialize, Serialize};
3
4#[derive(Debug, thiserror::Error)]
5pub enum OpenAIError {
6 #[error("http error: {0}")]
8 Reqwest(#[from] reqwest::Error),
9 #[error("{0}")]
11 ApiError(ApiError),
12 #[error("failed to deserialize api response: {0}")]
14 JsonDeserialize(serde_json::Error),
15 #[error("failed to save file: {0}")]
17 FileSave(String),
18 #[error("failed to read file: {0}")]
20 FileRead(String),
21 #[error("stream failed: {0}")]
23 Stream(String),
24 #[error("invalid args: {0}")]
27 InvalidArgument(String),
28}
29
30#[derive(Debug, Serialize, Deserialize, Clone)]
32pub struct ApiError {
33 pub message: String,
34 #[serde(rename = "type")]
35 pub kind: Option<String>,
36 pub param: Option<String>,
37 pub code: Option<String>,
38}
39
40impl std::fmt::Display for ApiError {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45 let mut parts = Vec::new();
46
47 if let Some(kind) = &self.kind {
48 parts.push(format!("{kind}:"));
49 }
50
51 parts.push(self.message.clone());
52
53 if let Some(param) = &self.param {
54 parts.push(format!("(param: {param})"));
55 }
56
57 if let Some(code) = &self.code {
58 parts.push(format!("(code: {code})"));
59 }
60
61 write!(f, "{}", parts.join(" "))
62 }
63}
64
65#[derive(Debug, Deserialize, Serialize)]
67pub struct WrappedError {
68 pub error: ApiError,
69}
70
71pub(crate) fn map_deserialization_error(e: serde_json::Error, bytes: &[u8]) -> OpenAIError {
72 tracing::error!(
73 "failed deserialization of: {}",
74 String::from_utf8_lossy(bytes)
75 );
76 OpenAIError::JsonDeserialize(e)
77}