objectiveai_sdk/http/
error.rs1use crate::error;
4
5#[derive(thiserror::Error, Debug)]
7pub enum HttpError {
8 #[error("deserialization error: {0}")]
12 DeserializationError(#[from] serde_path_to_error::Error<serde_json::Error>),
13
14 #[error("received bad status code: {code}, body: {body}")]
16 BadStatus {
17 code: reqwest::StatusCode,
19 body: serde_json::Value,
21 },
22
23 #[error("error fetching stream: {0}")]
25 StreamError(#[from] reqwest_eventsource::Error),
26
27 #[error("request error: {0}")]
29 RequestError(reqwest::Error),
30
31 #[error("streaming request error: {0}")]
35 StreamingRequestError(#[from] reqwest_eventsource::CannotCloneRequestError),
36
37 #[error("http error: {0}")]
39 HttpError(reqwest::Error),
40
41 #[error("multiple errors: {0}, {1}")]
43 MultipleErrors(Box<HttpError>, Box<HttpError>),
44
45 #[error(transparent)]
47 ApiError(#[from] error::ResponseError),
48
49 #[error("websocket upgrade failed: {0}")]
52 WsConnect(#[from] tokio_tungstenite::tungstenite::Error),
53
54 #[error("notify serialize: {0}")]
56 NotifySerialize(serde_json::Error),
57
58 #[error("notify send: {0}")]
60 NotifySend(tokio_tungstenite::tungstenite::Error),
61
62 #[error("notify channel closed before response arrived")]
65 NotifyChannelClosed,
66
67 #[error("notify rejected: code={code} message={message}")]
71 NotifyRejected {
72 code: u16,
73 message: serde_json::Value,
74 },
75}
76
77impl error::StatusError for HttpError {
78 fn status(&self) -> u16 {
79 match self {
80 HttpError::DeserializationError(_) => 500,
81 HttpError::BadStatus { code, .. } => code.as_u16(),
82 HttpError::StreamError(reqwest_eventsource::Error::Transport(
83 e,
84 )) => e.status().map(|s| s.as_u16()).unwrap_or(500),
85 HttpError::StreamError(
86 reqwest_eventsource::Error::InvalidStatusCode(code, _),
87 ) => code.as_u16(),
88 HttpError::StreamError(_) => 500,
89 HttpError::RequestError(e) => {
90 e.status().map(|s| s.as_u16()).unwrap_or(500)
91 }
92 HttpError::StreamingRequestError(_) => 500,
93 HttpError::HttpError(e) => {
94 e.status().map(|s| s.as_u16()).unwrap_or(500)
95 }
96 HttpError::MultipleErrors(e1, e2) => {
97 let s2 = e2.status();
98 if s2 != 500 { s2 } else { e1.status() }
99 }
100 HttpError::ApiError(e) => e.status(),
101 HttpError::WsConnect(_) => 500,
102 HttpError::NotifySerialize(_) => 500,
103 HttpError::NotifySend(_) => 500,
104 HttpError::NotifyChannelClosed => 500,
105 HttpError::NotifyRejected { code, .. } => *code,
106 }
107 }
108
109 fn message(&self) -> Option<serde_json::Value> {
110 Some(serde_json::json!({
111 "kind": "objectiveai_client",
112 "error": match self {
113 HttpError::DeserializationError(e) => serde_json::json!({
114 "kind": "deserialization",
115 "error": e.to_string(),
116 }),
117 HttpError::BadStatus { body, .. } => serde_json::json!({
118 "kind": "bad_status",
119 "error": body,
120 }),
121 HttpError::StreamError(e) => serde_json::json!({
122 "kind": "stream_error",
123 "error": e.to_string(),
124 }),
125 HttpError::RequestError(e) => serde_json::json!({
126 "kind": "request_error",
127 "error": e.to_string(),
128 }),
129 HttpError::StreamingRequestError(e) => serde_json::json!({
130 "kind": "streaming_request_error",
131 "error": e.to_string(),
132 }),
133 HttpError::HttpError(e) => serde_json::json!({
134 "kind": "http_error",
135 "error": e.to_string(),
136 }),
137 HttpError::MultipleErrors(e1, e2) => serde_json::json!({
138 "kind": "multiple",
139 "error_1": e1.message(),
140 "error_2": e2.message(),
141 }),
142 HttpError::ApiError(e) => serde_json::json!({
143 "kind": "api_error",
144 "error": e.message(),
145 }),
146 HttpError::WsConnect(e) => serde_json::json!({
147 "kind": "ws_connect",
148 "error": e.to_string(),
149 }),
150 HttpError::NotifySerialize(e) => serde_json::json!({
151 "kind": "notify_serialize",
152 "error": e.to_string(),
153 }),
154 HttpError::NotifySend(e) => serde_json::json!({
155 "kind": "notify_send",
156 "error": e.to_string(),
157 }),
158 HttpError::NotifyChannelClosed => serde_json::json!({
159 "kind": "notify_channel_closed",
160 }),
161 HttpError::NotifyRejected { code, message } => serde_json::json!({
162 "kind": "notify_rejected",
163 "code": code,
164 "message": message,
165 }),
166 }
167 }))
168 }
169}