litellm_rs/utils/error/gateway_error/
http_mapping.rs1use super::types::GatewayError;
4use crate::core::providers::unified_provider::{
5 ProviderHttpErrorFacts, provider_http_error_facts as provider_core_http_error_facts,
6};
7use actix_web::http::StatusCode;
8
9#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
11pub struct HttpErrorHeaders {
12 pub retry_after: Option<u64>,
13 pub rpm_limit: Option<u32>,
14 pub tpm_limit: Option<u32>,
15}
16
17#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub struct HttpErrorFacts {
20 pub status: StatusCode,
21 pub gateway_code: &'static str,
22 pub openai_error_type: &'static str,
23 pub openai_code: &'static str,
24 pub headers: HttpErrorHeaders,
25}
26
27impl HttpErrorFacts {
28 const fn new(
29 status: StatusCode,
30 gateway_code: &'static str,
31 openai_error_type: &'static str,
32 openai_code: &'static str,
33 ) -> Self {
34 Self {
35 status,
36 gateway_code,
37 openai_error_type,
38 openai_code,
39 headers: HttpErrorHeaders {
40 retry_after: None,
41 rpm_limit: None,
42 tpm_limit: None,
43 },
44 }
45 }
46
47 const fn with_headers(mut self, headers: HttpErrorHeaders) -> Self {
48 self.headers = headers;
49 self
50 }
51}
52
53pub fn gateway_http_error_facts(error: &GatewayError) -> HttpErrorFacts {
54 match error {
55 GatewayError::Config(_) => facts(
56 StatusCode::INTERNAL_SERVER_ERROR,
57 "CONFIG_ERROR",
58 "server_error",
59 "internal_error",
60 ),
61 GatewayError::Storage(_) => facts(
62 StatusCode::SERVICE_UNAVAILABLE,
63 "STORAGE_ERROR",
64 "server_error",
65 "service_unavailable",
66 ),
67 GatewayError::Auth(_) => facts(
68 StatusCode::UNAUTHORIZED,
69 "AUTH_ERROR",
70 "authentication_error",
71 "authentication_error",
72 ),
73 GatewayError::Forbidden(_) => facts(
74 StatusCode::FORBIDDEN,
75 "FORBIDDEN",
76 "permission_error",
77 "permission_denied",
78 ),
79 GatewayError::Provider(provider_error) => {
80 provider_facts_to_http_error_facts(provider_core_http_error_facts(provider_error))
81 }
82 GatewayError::RateLimit {
83 retry_after,
84 rpm_limit,
85 tpm_limit,
86 ..
87 } => facts(
88 StatusCode::TOO_MANY_REQUESTS,
89 "RATE_LIMIT_EXCEEDED",
90 "rate_limit_error",
91 "rate_limit_exceeded",
92 )
93 .with_headers(HttpErrorHeaders {
94 retry_after: *retry_after,
95 rpm_limit: *rpm_limit,
96 tpm_limit: *tpm_limit,
97 }),
98 GatewayError::Validation(_) => facts(
99 StatusCode::BAD_REQUEST,
100 "VALIDATION_ERROR",
101 "invalid_request_error",
102 "invalid_request",
103 ),
104 GatewayError::NotFound(_) => facts(
105 StatusCode::NOT_FOUND,
106 "NOT_FOUND",
107 "invalid_request_error",
108 "not_found",
109 ),
110 GatewayError::Conflict(_) => facts(
111 StatusCode::CONFLICT,
112 "CONFLICT",
113 "invalid_request_error",
114 "conflict",
115 ),
116 GatewayError::BadRequest(_) => facts(
117 StatusCode::BAD_REQUEST,
118 "BAD_REQUEST",
119 "invalid_request_error",
120 "invalid_request",
121 ),
122 GatewayError::Timeout(_) => facts(
123 StatusCode::REQUEST_TIMEOUT,
124 "TIMEOUT",
125 "server_error",
126 "timeout",
127 ),
128 GatewayError::Unavailable(_) => facts(
129 StatusCode::SERVICE_UNAVAILABLE,
130 "SERVICE_UNAVAILABLE",
131 "server_error",
132 "service_unavailable",
133 ),
134 GatewayError::Network(_) => facts(
135 StatusCode::BAD_GATEWAY,
136 "NETWORK_ERROR",
137 "server_error",
138 "network_error",
139 ),
140 GatewayError::Internal(_) => facts(
141 StatusCode::INTERNAL_SERVER_ERROR,
142 "INTERNAL_ERROR",
143 "server_error",
144 "internal_error",
145 ),
146 GatewayError::NotImplemented(_) => facts(
147 StatusCode::NOT_IMPLEMENTED,
148 "NOT_IMPLEMENTED",
149 "invalid_request_error",
150 "not_implemented",
151 ),
152 GatewayError::Serialization(_) => facts(
153 StatusCode::BAD_REQUEST,
154 "SERIALIZATION_ERROR",
155 "invalid_request_error",
156 "invalid_request",
157 ),
158 GatewayError::HttpClient(_) => facts(
159 StatusCode::BAD_GATEWAY,
160 "HTTP_CLIENT_ERROR",
161 "server_error",
162 "network_error",
163 ),
164 GatewayError::Io(_) => facts(
165 StatusCode::INTERNAL_SERVER_ERROR,
166 "IO_ERROR",
167 "server_error",
168 "internal_error",
169 ),
170 }
171}
172
173const fn facts(
174 status: StatusCode,
175 gateway_code: &'static str,
176 openai_error_type: &'static str,
177 openai_code: &'static str,
178) -> HttpErrorFacts {
179 HttpErrorFacts::new(status, gateway_code, openai_error_type, openai_code)
180}
181
182fn provider_facts_to_http_error_facts(core_facts: ProviderHttpErrorFacts) -> HttpErrorFacts {
183 HttpErrorFacts::new(
184 status_from_u16(core_facts.status),
185 core_facts.gateway_code,
186 core_facts.openai_error_type,
187 core_facts.openai_code,
188 )
189 .with_headers(HttpErrorHeaders {
190 retry_after: core_facts.headers.retry_after,
191 rpm_limit: core_facts.headers.rpm_limit,
192 tpm_limit: core_facts.headers.tpm_limit,
193 })
194}
195
196fn status_from_u16(status: u16) -> StatusCode {
197 StatusCode::from_u16(status).unwrap_or(StatusCode::BAD_GATEWAY)
198}