Files
rustical/crates/store/src/error.rs
2025-10-27 20:12:21 +01:00

59 lines
1.5 KiB
Rust

use axum::response::IntoResponse;
use http::StatusCode;
use tracing::error;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Not found")]
NotFound,
#[error("Resource already exists and overwrite=false")]
AlreadyExists,
#[error("Invalid principal type: {0}")]
InvalidPrincipalType(String),
#[error("Read-only")]
ReadOnly,
#[error("Error generating password hash")]
PasswordHash,
#[error(transparent)]
IO(#[from] std::io::Error),
#[error(transparent)]
Other(#[from] anyhow::Error),
#[error(transparent)]
IcalError(#[from] rustical_ical::Error),
}
impl Error {
#[must_use]
pub const fn status_code(&self) -> StatusCode {
match self {
Self::NotFound => StatusCode::NOT_FOUND,
Self::AlreadyExists => StatusCode::CONFLICT,
Self::ReadOnly => StatusCode::FORBIDDEN,
Self::IcalError(err) => err.status_code(),
Self::InvalidPrincipalType(_) => StatusCode::BAD_REQUEST,
_ => StatusCode::INTERNAL_SERVER_ERROR,
}
}
}
impl IntoResponse for Error {
fn into_response(self) -> axum::response::Response {
if matches!(
self.status_code(),
StatusCode::INTERNAL_SERVER_ERROR
| StatusCode::PRECONDITION_FAILED
| StatusCode::CONFLICT
) {
error!("{self}");
}
(self.status_code(), self.to_string()).into_response()
}
}