longbridge_httpcli/
error.rs1use std::error::Error;
2
3use longbridge_geo::DcRegion;
4use reqwest::{StatusCode, header::HeaderMap};
5
6use crate::qs::QsError;
7
8#[derive(Debug, thiserror::Error)]
10pub enum HttpClientError {
11 #[error("invalid request method")]
13 InvalidRequestMethod,
14
15 #[error("invalid api key")]
17 InvalidApiKey,
18
19 #[error("invalid access token")]
21 InvalidAccessToken,
22
23 #[error("missing environment variable: {name}")]
25 MissingEnvVar {
26 name: String,
28 },
29
30 #[error("unexpected response")]
32 UnexpectedResponse,
33
34 #[error("request timeout")]
36 RequestTimeout,
37
38 #[error(
41 "this API ({path}) is only available in the {required} data center and is not supported for your {current}-region account"
42 )]
43 DcRegionRestricted {
44 path: String,
46 required: DcRegion,
48 current: DcRegion,
50 },
51
52 #[error("openapi error: code={code}: {message}")]
54 OpenApi {
55 code: i32,
57 message: String,
59 trace_id: String,
61 },
62
63 #[error("deserialize response body error: {0}")]
65 DeserializeResponseBody(String),
66
67 #[error("serialize request body error: {0}")]
69 SerializeRequestBody(String),
70
71 #[error("serialize query string error: {0}")]
73 SerializeQueryString(#[from] QsError),
74
75 #[error("status error: {0}")]
77 BadStatus(StatusCode),
78
79 #[error("unexpected HTTP response: status={status}, trace_id={trace_id}, body={body}")]
81 UnexpectedHttpResponse {
82 status: StatusCode,
84 trace_id: String,
86 headers: Box<HeaderMap>,
88 body: String,
90 },
91
92 #[error(transparent)]
94 Http(#[from] HttpError),
95
96 #[error("connections limitation is hit, limit = {limit}, online = {online}")]
98 ConnectionLimitExceeded {
99 limit: i32,
101 online: i32,
103 },
104
105 #[error("oauth error: {0}")]
107 OAuth(String),
108
109 #[error("sse stream error: {0}")]
111 Sse(String),
112}
113
114#[derive(Debug)]
116pub struct HttpError(pub reqwest::Error);
117
118impl From<reqwest::Error> for HttpError {
119 #[inline]
120 fn from(err: reqwest::Error) -> Self {
121 Self(err)
122 }
123}
124
125impl std::fmt::Display for HttpError {
126 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127 if let Some(source) = self.0.source() {
128 write!(f, "{}: {}", self.0, source)
129 } else {
130 self.0.fmt(f)
131 }
132 }
133}
134
135impl std::error::Error for HttpError {}
136
137pub type HttpClientResult<T, E = HttpClientError> = std::result::Result<T, E>;