Skip to main content

routa_core/
error.rs

1//! Core error type for the Routa platform.
2//!
3//! `ServerError` is used throughout the core domain (stores, RPC, etc.).
4//! When the `axum` feature is enabled, it also implements `IntoResponse`
5//! so it can be used directly as an axum handler error type.
6
7#[derive(Debug, thiserror::Error)]
8pub enum ServerError {
9    #[error("Database error: {0}")]
10    Database(String),
11
12    #[error("Not found: {0}")]
13    NotFound(String),
14
15    #[error("Bad request: {0}")]
16    BadRequest(String),
17
18    #[error("Conflict: {0}")]
19    Conflict(String),
20
21    #[error("Internal error: {0}")]
22    Internal(String),
23
24    #[error("Not implemented: {0}")]
25    NotImplemented(String),
26}
27
28// ---------------------------------------------------------------------------
29// axum integration (opt-in via feature flag)
30// ---------------------------------------------------------------------------
31
32#[cfg(feature = "axum")]
33impl axum::response::IntoResponse for ServerError {
34    fn into_response(self) -> axum::response::Response {
35        use axum::http::StatusCode;
36
37        let (status, message) = match &self {
38            ServerError::Database(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()),
39            ServerError::NotFound(msg) => (StatusCode::NOT_FOUND, msg.clone()),
40            ServerError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg.clone()),
41            ServerError::Conflict(msg) => (StatusCode::CONFLICT, msg.clone()),
42            ServerError::Internal(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()),
43            ServerError::NotImplemented(msg) => (StatusCode::NOT_IMPLEMENTED, msg.clone()),
44        };
45
46        let body = serde_json::json!({ "error": message });
47        (status, axum::Json(body)).into_response()
48    }
49}