1use axum::http::StatusCode;
6use axum::response::{IntoResponse, Response};
7use serde_json::json;
8
9pub enum ApiError {
11 Storage(tuitbot_core::error::StorageError),
13 NotFound(String),
15 BadRequest(String),
17 Conflict(String),
19 Internal(String),
21}
22
23impl From<tuitbot_core::error::StorageError> for ApiError {
24 fn from(err: tuitbot_core::error::StorageError) -> Self {
25 Self::Storage(err)
26 }
27}
28
29impl IntoResponse for ApiError {
30 fn into_response(self) -> Response {
31 let (status, message) = match self {
32 Self::Storage(e) => {
33 tracing::error!("storage error: {e}");
34 (StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
35 }
36 Self::NotFound(msg) => (StatusCode::NOT_FOUND, msg),
37 Self::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg),
38 Self::Conflict(msg) => (StatusCode::CONFLICT, msg),
39 Self::Internal(msg) => {
40 tracing::error!("internal error: {msg}");
41 (StatusCode::INTERNAL_SERVER_ERROR, msg)
42 }
43 };
44
45 let body = axum::Json(json!({ "error": message }));
46 (status, body).into_response()
47 }
48}