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(transparent)]
43 ApiError(#[from] error::ResponseError),
44
45 #[error("websocket upgrade failed: {0}")]
48 WsConnect(#[from] tokio_tungstenite::tungstenite::Error),
49
50 #[error("notify serialize: {0}")]
52 NotifySerialize(serde_json::Error),
53
54 #[error("notify send: {0}")]
56 NotifySend(tokio_tungstenite::tungstenite::Error),
57
58 #[error("notify channel closed before response arrived")]
61 NotifyChannelClosed,
62
63 #[error("notify rejected: code={code} message={message}")]
67 NotifyRejected {
68 code: u16,
69 message: serde_json::Value,
70 },
71}
72
73impl error::StatusError for HttpError {
74 fn status(&self) -> u16 {
75 match self {
76 HttpError::DeserializationError(_) => 500,
77 HttpError::BadStatus { code, .. } => code.as_u16(),
78 HttpError::StreamError(reqwest_eventsource::Error::Transport(
79 e,
80 )) => e.status().map(|s| s.as_u16()).unwrap_or(500),
81 HttpError::StreamError(
82 reqwest_eventsource::Error::InvalidStatusCode(code, _),
83 ) => code.as_u16(),
84 HttpError::StreamError(_) => 500,
85 HttpError::RequestError(e) => {
86 e.status().map(|s| s.as_u16()).unwrap_or(500)
87 }
88 HttpError::StreamingRequestError(_) => 500,
89 HttpError::HttpError(e) => {
90 e.status().map(|s| s.as_u16()).unwrap_or(500)
91 }
92 HttpError::ApiError(e) => e.status(),
93 HttpError::WsConnect(_) => 500,
94 HttpError::NotifySerialize(_) => 500,
95 HttpError::NotifySend(_) => 500,
96 HttpError::NotifyChannelClosed => 500,
97 HttpError::NotifyRejected { code, .. } => *code,
98 }
99 }
100
101 fn message(&self) -> Option<serde_json::Value> {
102 Some(serde_json::json!({
103 "kind": "objectiveai_client",
104 "error": match self {
105 HttpError::DeserializationError(e) => serde_json::json!({
106 "kind": "deserialization",
107 "error": e.to_string(),
108 }),
109 HttpError::BadStatus { body, .. } => serde_json::json!({
110 "kind": "bad_status",
111 "error": body,
112 }),
113 HttpError::StreamError(e) => serde_json::json!({
114 "kind": "stream_error",
115 "error": e.to_string(),
116 }),
117 HttpError::RequestError(e) => serde_json::json!({
118 "kind": "request_error",
119 "error": e.to_string(),
120 }),
121 HttpError::StreamingRequestError(e) => serde_json::json!({
122 "kind": "streaming_request_error",
123 "error": e.to_string(),
124 }),
125 HttpError::HttpError(e) => serde_json::json!({
126 "kind": "http_error",
127 "error": e.to_string(),
128 }),
129 HttpError::ApiError(e) => serde_json::json!({
130 "kind": "api_error",
131 "error": e.message(),
132 }),
133 HttpError::WsConnect(e) => serde_json::json!({
134 "kind": "ws_connect",
135 "error": e.to_string(),
136 }),
137 HttpError::NotifySerialize(e) => serde_json::json!({
138 "kind": "notify_serialize",
139 "error": e.to_string(),
140 }),
141 HttpError::NotifySend(e) => serde_json::json!({
142 "kind": "notify_send",
143 "error": e.to_string(),
144 }),
145 HttpError::NotifyChannelClosed => serde_json::json!({
146 "kind": "notify_channel_closed",
147 }),
148 HttpError::NotifyRejected { code, message } => serde_json::json!({
149 "kind": "notify_rejected",
150 "code": code,
151 "message": message,
152 }),
153 }
154 }))
155 }
156}