Skip to main content

statespace_server/
error.rs

1//! Error types with HTTP status code mapping.
2
3use axum::http::StatusCode;
4use axum::response::{IntoResponse, Response};
5
6pub use statespace_tool_runtime::Error;
7pub type Result<T> = std::result::Result<T, Error>;
8
9pub trait ErrorExt {
10    fn status_code(&self) -> StatusCode;
11}
12
13impl ErrorExt for Error {
14    fn status_code(&self) -> StatusCode {
15        match self {
16            Error::InvalidCommand(_)
17            | Error::CommandNotFound { .. }
18            | Error::NoFrontmatter
19            | Error::FrontmatterParse(_) => StatusCode::BAD_REQUEST,
20
21            Error::PathTraversal { .. } | Error::Security(_) => StatusCode::FORBIDDEN,
22
23            Error::NotFound(_) => StatusCode::NOT_FOUND,
24            Error::Timeout => StatusCode::REQUEST_TIMEOUT,
25            Error::OutputTooLarge { .. } => StatusCode::PAYLOAD_TOO_LARGE,
26            Error::Network(_) => StatusCode::BAD_GATEWAY,
27
28            _ => StatusCode::INTERNAL_SERVER_ERROR,
29        }
30    }
31}
32
33#[derive(Debug)]
34pub struct ServerError(pub Error);
35
36impl From<Error> for ServerError {
37    fn from(e: Error) -> Self {
38        Self(e)
39    }
40}
41
42impl IntoResponse for ServerError {
43    fn into_response(self) -> Response {
44        let status = self.0.status_code();
45        let body = self.0.user_message();
46        (status, body).into_response()
47    }
48}