1use axum::http::StatusCode;
2use axum::response::{IntoResponse, Response};
3use axum::Json;
4use hehe_agent::AgentError;
5use serde::Serialize;
6use thiserror::Error;
7
8#[derive(Error, Debug)]
9pub enum ServerError {
10 #[error("Bad request: {0}")]
11 BadRequest(String),
12
13 #[error("Not found: {0}")]
14 NotFound(String),
15
16 #[error("Internal error: {0}")]
17 Internal(String),
18
19 #[error("Agent error: {0}")]
20 Agent(#[from] AgentError),
21
22 #[error("Serialization error: {0}")]
23 Serialization(#[from] serde_json::Error),
24}
25
26pub type Result<T> = std::result::Result<T, ServerError>;
27
28#[derive(Serialize)]
29struct ErrorResponse {
30 error: String,
31 code: u16,
32}
33
34impl IntoResponse for ServerError {
35 fn into_response(self) -> Response {
36 let (status, message) = match &self {
37 ServerError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg.clone()),
38 ServerError::NotFound(msg) => (StatusCode::NOT_FOUND, msg.clone()),
39 ServerError::Internal(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg.clone()),
40 ServerError::Agent(e) => (StatusCode::INTERNAL_SERVER_ERROR, e.to_string()),
41 ServerError::Serialization(e) => (StatusCode::BAD_REQUEST, e.to_string()),
42 };
43
44 let body = Json(ErrorResponse {
45 error: message,
46 code: status.as_u16(),
47 });
48
49 (status, body).into_response()
50 }
51}
52
53impl ServerError {
54 pub fn bad_request(msg: impl Into<String>) -> Self {
55 Self::BadRequest(msg.into())
56 }
57
58 pub fn not_found(msg: impl Into<String>) -> Self {
59 Self::NotFound(msg.into())
60 }
61
62 pub fn internal(msg: impl Into<String>) -> Self {
63 Self::Internal(msg.into())
64 }
65}