use axum::http::StatusCode;
use axum::response::{IntoResponse, Response};
use axum::Json;
use hehe_agent::AgentError;
use serde::Serialize;
use thiserror::Error;
#[derive(Error, Debug)]
pub enum ServerError {
#[error("Bad request: {0}")]
BadRequest(String),
#[error("Not found: {0}")]
NotFound(String),
#[error("Internal error: {0}")]
Internal(String),
#[error("Agent error: {0}")]
Agent(#[from] AgentError),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
}
pub type Result<T> = std::result::Result<T, ServerError>;
#[derive(Serialize)]
struct ErrorResponse {
error: String,
code: u16,
}
impl IntoResponse for ServerError {
fn into_response(self) -> Response {
let (status, message) = match &self {
ServerError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg.clone()),
ServerError::NotFound(msg) => (StatusCode::NOT_FOUND, msg.clone()),
ServerError::Internal(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()),
ServerError::Agent(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()),
ServerError::Serialization(e) => (StatusCode::BAD_REQUEST, e.to_string()),
};
let body = Json(ErrorResponse {
error: message,
code: status.as_u16(),
});
(status, body).into_response()
}
}
impl ServerError {
pub fn bad_request(msg: impl Into<String>) -> Self {
Self::BadRequest(msg.into())
}
pub fn not_found(msg: impl Into<String>) -> Self {
Self::NotFound(msg.into())
}
pub fn internal(msg: impl Into<String>) -> Self {
Self::Internal(msg.into())
}
}