1use serde::{Deserialize, Serialize};
4
5pub(crate) fn enum_to_string<T: Serialize>(value: &T) -> Result<String, OpenAIError> {
10 let v = serde_json::to_value(value)?;
11 v.as_str()
12 .map(|s| s.to_string())
13 .ok_or_else(|| OpenAIError::InvalidArgument(format!("expected string enum, got {v}")))
14}
15
16#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct ErrorResponse {
19 pub error: ApiErrorDetail,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct ApiErrorDetail {
25 pub message: String,
26 #[serde(rename = "type")]
27 pub type_: Option<String>,
28 pub param: Option<String>,
29 pub code: Option<String>,
30}
31
32#[derive(Debug, thiserror::Error)]
34pub enum OpenAIError {
35 #[error("API error (status {status}): {message}")]
37 ApiError {
38 status: u16,
39 message: String,
40 type_: Option<String>,
41 code: Option<String>,
42 request_id: Option<String>,
44 },
45
46 #[error("request error: {0}")]
48 RequestError(#[from] reqwest::Error),
49
50 #[error("JSON error: {0}")]
52 JsonError(#[from] serde_json::Error),
53
54 #[error("stream error: {0}")]
56 StreamError(String),
57
58 #[error("invalid argument: {0}")]
60 InvalidArgument(String),
61
62 #[cfg(feature = "websocket")]
64 #[error("websocket error: {0}")]
65 WebSocketError(String),
66}