use super::AppJson;
use axum::extract::rejection::JsonRejection;
use axum::http::StatusCode;
use axum::response::IntoResponse;
use axum::response::Response;
use serde::Serialize;
use std::result::Result as StdResult;
pub type Result<T> = StdResult<T, AppError>;
pub enum AppError {
JsonRejection(JsonRejection),
DbError(surrealdb::Error),
InvalidCredentials,
Arbitrary(&'static str, String),
}
impl IntoResponse for AppError {
fn into_response(self) -> Response {
#[derive(Serialize)]
struct ErrorResponse {
code: &'static str,
message: String,
}
let (status, code, message) = match self {
AppError::JsonRejection(rejection) => {
(rejection.status(), "invalid-json", rejection.body_text())
}
AppError::DbError(dbe) => {
tracing::error!(err_source = "surrealdb", "Database error: {dbe}");
(
StatusCode::INTERNAL_SERVER_ERROR,
"db-error",
"a database error occured".to_string(),
)
}
AppError::InvalidCredentials => (
StatusCode::UNAUTHORIZED,
"invalid-credentials",
"Invalid credentials given.".to_string(),
),
AppError::Arbitrary(code, message) => {
(StatusCode::INTERNAL_SERVER_ERROR, code, message)
}
};
(status, AppJson(ErrorResponse { code, message })).into_response()
}
}
impl From<JsonRejection> for AppError {
fn from(value: JsonRejection) -> Self {
Self::JsonRejection(value)
}
}
impl From<surrealdb::Error> for AppError {
fn from(value: surrealdb::Error) -> Self {
Self::DbError(value)
}
}