zksvm_api_types/
errors.rs1use std::error::Error;
2
3use axum::{
4 http::StatusCode,
5 response::{IntoResponse, Response},
6 Json,
7};
8use serde::{Deserialize, Serialize};
9
10#[derive(Debug, thiserror::Error)]
12pub enum DBError {
13 #[error("Failed to read environment variable: {0}")]
15 EnvVar(String),
16 #[error("Failed to read from DB: {0}")]
18 Read(String),
19 #[error("Failed to write to DB: {0}")]
21 Write(String),
22}
23
24#[derive(Debug, thiserror::Error)]
26pub enum ApiError {
27 #[error("Auth error: {0}")]
29 Auth(String),
30 #[error("Environment variable not found: {0}")]
32 EnvVar(String),
33 #[error("Invalid UUID received: {0}")]
35 Uuid(#[from] uuid::Error),
36 #[error("Exceeded transaction limit for session: {0}")]
38 MaxTxLimit(u64),
39 #[error("Session already initiated")]
41 SessionAlreadyInitiated,
42 #[error(transparent)]
44 DB(#[from] DBError),
45 #[error(transparent)]
47 CatchAll(#[from] Box<dyn Error>),
48}
49
50pub type ApiResult<T = ()> = Result<T, ApiError>;
51
52#[derive(Debug, Serialize, Deserialize)]
53#[serde(tag = "status", rename_all = "snake_case")]
54pub enum ApiResponse<T: Serialize = ()> {
55 Success {
56 #[serde(flatten)]
57 data: T,
58 },
59 Error {
60 code: u16,
61 message: String,
62 },
63}
64
65impl<T: Serialize> From<ApiError> for ApiResponse<T> {
66 fn from(err: ApiError) -> Self {
67 use ApiError::*;
68 let code = match err {
69 EnvVar(_) | DB(_) | CatchAll(_) => StatusCode::INTERNAL_SERVER_ERROR,
70 Uuid(_) | MaxTxLimit(_) | SessionAlreadyInitiated => StatusCode::BAD_REQUEST,
71 Auth(_) => StatusCode::UNAUTHORIZED,
72 }
73 .into();
74
75 ApiResponse::Error {
76 code,
77 message: format!("{err:?}"),
78 }
79 }
80}
81
82impl<T: Serialize> ApiResponse<T> {
83 pub fn success(data: T) -> ApiResult<Self> {
84 Ok(Self::Success { data })
85 }
86}
87
88impl<T: Serialize> IntoResponse for ApiResponse<T> {
89 fn into_response(self) -> Response {
90 Json(self).into_response()
91 }
92}
93
94impl IntoResponse for ApiError {
95 fn into_response(self) -> Response {
96 ApiResponse::<()>::from(self).into_response()
97 }
98}