use {axum::{http::StatusCode,
response::{IntoResponse,
Response}},
thiserror::Error};
pub type Result<T> = std::result::Result<T, JetError>;
#[derive(Error, Debug)]
pub enum JetError {
#[error("Failed to decode protobuf: {0}")]
ProtobufDecode(#[from] prost::DecodeError),
#[error("Failed to encode protobuf: {0}")]
ProtobufEncode(#[from] prost::EncodeError),
#[error("Invalid content type: expected {expected}, got {actual}")]
InvalidContentType { expected: String, actual: String },
#[error("Missing Content-Type header")]
MissingContentType,
#[error("Request body too large: {size} bytes (max: {max})")]
BodyTooLarge { size: usize, max: usize },
#[error("HTTP client error: {0}")]
HttpClient(#[from] reqwest::Error),
#[error("JSON error: {0}")]
Json(#[from] serde_json::Error),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("Failed to bind server: {0}")]
ServerBind(String),
#[error("Internal server error: {0}")]
Internal(String),
#[error("Bad request: {0}")]
BadRequest(String),
#[error("Not found: {0}")]
NotFound(String),
#[error("Unauthorized: {0}")]
Unauthorized(String),
#[error("Forbidden: {0}")]
Forbidden(String),
}
impl JetError {
pub fn status_code(&self) -> StatusCode {
match self {
| JetError::ProtobufDecode(_) => StatusCode::BAD_REQUEST,
| JetError::ProtobufEncode(_) => StatusCode::INTERNAL_SERVER_ERROR,
| JetError::InvalidContentType { .. } => StatusCode::UNSUPPORTED_MEDIA_TYPE,
| JetError::MissingContentType => StatusCode::BAD_REQUEST,
| JetError::BodyTooLarge { .. } => StatusCode::PAYLOAD_TOO_LARGE,
| JetError::HttpClient(_) => StatusCode::BAD_GATEWAY,
| JetError::Json(_) => StatusCode::BAD_REQUEST,
| JetError::Io(_) => StatusCode::INTERNAL_SERVER_ERROR,
| JetError::ServerBind(_) => StatusCode::INTERNAL_SERVER_ERROR,
| JetError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
| JetError::BadRequest(_) => StatusCode::BAD_REQUEST,
| JetError::NotFound(_) => StatusCode::NOT_FOUND,
| JetError::Unauthorized(_) => StatusCode::UNAUTHORIZED,
| JetError::Forbidden(_) => StatusCode::FORBIDDEN,
}
}
}
impl IntoResponse for JetError {
fn into_response(self) -> Response {
let status = self.status_code();
let body = self.to_string();
(status, body).into_response()
}
}