80 lines
2.7 KiB
Rust
80 lines
2.7 KiB
Rust
use axum::http::StatusCode;
|
|
use axum::response::{IntoResponse, Response};
|
|
use axum::Json;
|
|
use serde_json::{json, Value};
|
|
use thiserror::Error;
|
|
|
|
#[derive(Error, Debug)]
|
|
pub enum AppError {
|
|
#[error("Worker error: {0}")]
|
|
Worker(#[from] worker::Error),
|
|
|
|
#[error("Database query failed")]
|
|
Database,
|
|
|
|
#[error("Not found: {0}")]
|
|
NotFound(String),
|
|
|
|
#[error("Invalid request: {0}")]
|
|
BadRequest(String),
|
|
|
|
#[error("Unauthorized: {0}")]
|
|
Unauthorized(String),
|
|
|
|
#[error("Too many requests: {0}")]
|
|
TooManyRequests(String),
|
|
|
|
#[error("Cryptography error: {0}")]
|
|
Crypto(String),
|
|
|
|
#[error(transparent)]
|
|
JsonWebToken(#[from] jsonwebtoken::errors::Error),
|
|
|
|
#[error("Internal server error")]
|
|
Internal,
|
|
|
|
#[error("Two factor authentication required")]
|
|
TwoFactorRequired(Value),
|
|
}
|
|
|
|
impl IntoResponse for AppError {
|
|
fn into_response(self) -> Response {
|
|
match self {
|
|
AppError::TwoFactorRequired(json_body) => {
|
|
// Return 400 Bad Request with the 2FA required JSON response as expected by clients
|
|
(StatusCode::BAD_REQUEST, Json(json_body)).into_response()
|
|
}
|
|
other => {
|
|
let (status, error_message) = match other {
|
|
AppError::Worker(e) => (
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
format!("Worker error: {}", e),
|
|
),
|
|
AppError::Database => (
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
"Database error".to_string(),
|
|
),
|
|
AppError::NotFound(msg) => (StatusCode::NOT_FOUND, msg),
|
|
AppError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg),
|
|
AppError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg),
|
|
AppError::TooManyRequests(msg) => (StatusCode::TOO_MANY_REQUESTS, msg),
|
|
AppError::Crypto(msg) => (
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
format!("Crypto error: {}", msg),
|
|
),
|
|
AppError::JsonWebToken(_) => {
|
|
(StatusCode::UNAUTHORIZED, "Invalid token".to_string())
|
|
}
|
|
AppError::Internal => (
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
"Internal server error".to_string(),
|
|
),
|
|
AppError::TwoFactorRequired(_) => unreachable!(),
|
|
};
|
|
|
|
let body = Json(json!({ "error": error_message }));
|
|
(status, body).into_response()
|
|
}
|
|
}
|
|
}
|
|
}
|