Skip to main content

hypercall_runtime_api/
error.rs

1use axum::{
2    http::StatusCode,
3    response::{IntoResponse, Response},
4};
5use serde::Serialize;
6use sonic_rs::json;
7
8use crate::sonic_json::SonicJson;
9
10/// API error response body
11#[derive(Debug, Serialize)]
12pub struct ApiErrorBody {
13    pub error: String,
14    pub message: String,
15}
16
17/// API error type that returns JSON responses
18#[derive(Debug)]
19pub struct ApiError {
20    pub status: StatusCode,
21    pub error: String,
22    pub message: String,
23}
24
25impl ApiError {
26    pub fn new(status: StatusCode, error: impl Into<String>, message: impl Into<String>) -> Self {
27        Self {
28            status,
29            error: error.into(),
30            message: message.into(),
31        }
32    }
33
34    pub fn bad_request(message: impl Into<String>) -> Self {
35        Self::new(StatusCode::BAD_REQUEST, "bad_request", message)
36    }
37
38    pub fn unsupported_action(message: impl Into<String>) -> Self {
39        Self::new(StatusCode::BAD_REQUEST, "unsupported_action", message)
40    }
41
42    pub fn invalid_field(message: impl Into<String>) -> Self {
43        Self::new(StatusCode::BAD_REQUEST, "invalid_field", message)
44    }
45
46    pub fn invalid_signature(message: impl Into<String>) -> Self {
47        Self::new(StatusCode::BAD_REQUEST, "invalid_signature", message)
48    }
49
50    pub fn unknown_account(message: impl Into<String>) -> Self {
51        Self::new(StatusCode::BAD_REQUEST, "unknown_account", message)
52    }
53
54    pub fn unauthorized(message: impl Into<String>) -> Self {
55        Self::new(StatusCode::UNAUTHORIZED, "unauthorized", message)
56    }
57
58    pub fn forbidden(message: impl Into<String>) -> Self {
59        Self::new(StatusCode::FORBIDDEN, "forbidden", message)
60    }
61
62    pub fn not_found(message: impl Into<String>) -> Self {
63        Self::new(StatusCode::NOT_FOUND, "not_found", message)
64    }
65
66    pub fn internal_error(message: impl Into<String>) -> Self {
67        Self::new(StatusCode::INTERNAL_SERVER_ERROR, "internal_error", message)
68    }
69
70    pub fn gateway_timeout(message: impl Into<String>) -> Self {
71        Self::new(StatusCode::GATEWAY_TIMEOUT, "gateway_timeout", message)
72    }
73}
74
75impl IntoResponse for ApiError {
76    fn into_response(self) -> Response {
77        let body = json!({
78            "error": self.error,
79            "message": self.message
80        });
81        (self.status, SonicJson(body)).into_response()
82    }
83}