1use axum::response::IntoResponse;
2use thiserror::Error;
3
4use crate::rest::response::ApiResponse;
5
6pub type RestResult<T> = Result<T, RestError>;
8
9#[derive(Debug, Error)]
11pub enum RestError {
12 #[error("unauthorized")]
13 Unauthorized,
14
15 #[error("request timed out")]
16 Timeout,
17
18 #[error("service unavailable: {0}")]
19 ServiceUnavailable(String),
20
21 #[error("concurrency limit reached")]
22 ConcurrencyLimit,
23
24 #[error("rate limit exceeded")]
25 RateLimited,
26
27 #[error("service overloaded")]
28 Overloaded,
29
30 #[error("bad request: {0}")]
31 BadRequest(String),
32
33 #[error("internal error: {0}")]
34 Internal(String),
35}
36
37impl RestError {
38 pub fn code(&self) -> &'static str {
40 match self {
41 Self::Unauthorized => "UNAUTHORIZED",
42 Self::Timeout => "TIMEOUT",
43 Self::ServiceUnavailable(_) => "SERVICE_UNAVAILABLE",
44 Self::ConcurrencyLimit => "CONCURRENCY_LIMIT",
45 Self::RateLimited => "RATE_LIMITED",
46 Self::Overloaded => "OVERLOADED",
47 Self::BadRequest(_) => "BAD_REQUEST",
48 Self::Internal(_) => "INTERNAL",
49 }
50 }
51}
52
53impl IntoResponse for RestError {
54 fn into_response(self) -> axum::response::Response {
55 ApiResponse::<()>::fail(self.code(), self.to_string()).into_response()
56 }
57}