gitdataai/lib/api/src/error.rs
2026-05-30 01:38:40 +08:00

92 lines
4.1 KiB
Rust

use actix_web::{HttpResponse, error::ResponseError, http::StatusCode};
use serde::Serialize;
use service::error::AppError;
pub fn ok_json<T: Serialize>(data: T) -> Result<HttpResponse, ApiError> {
Ok(HttpResponse::Ok().json(data))
}
pub struct ApiError(pub AppError);
impl From<AppError> for ApiError {
fn from(err: AppError) -> Self {
ApiError(err)
}
}
impl std::fmt::Display for ApiError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl std::fmt::Debug for ApiError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl ResponseError for ApiError {
fn status_code(&self) -> StatusCode {
match &self.0 {
AppError::Unauthorized => StatusCode::UNAUTHORIZED,
AppError::UserNotFound => StatusCode::NOT_FOUND,
AppError::InvalidPassword => StatusCode::UNAUTHORIZED,
AppError::PasswordTooWeak => StatusCode::BAD_REQUEST,
AppError::CaptchaError => StatusCode::BAD_REQUEST,
AppError::TwoFactorRequired => {
StatusCode::from_u16(402).unwrap_or(StatusCode::BAD_REQUEST)
}
AppError::TwoFactorAlreadyEnabled => StatusCode::CONFLICT,
AppError::TwoFactorNotSetup => StatusCode::NOT_FOUND,
AppError::InvalidTwoFactorCode => StatusCode::BAD_REQUEST,
AppError::TwoFactorNotEnabled => StatusCode::NOT_FOUND,
AppError::RsaGenerationError => StatusCode::INTERNAL_SERVER_ERROR,
AppError::RsaDecodeError => StatusCode::BAD_REQUEST,
AppError::UserNameExists => StatusCode::CONFLICT,
AppError::EmailExists => StatusCode::CONFLICT,
AppError::AccountAlreadyExists => StatusCode::CONFLICT,
AppError::TxnError => StatusCode::INTERNAL_SERVER_ERROR,
AppError::PasswordHashError(_) => StatusCode::INTERNAL_SERVER_ERROR,
AppError::DatabaseError(_) => StatusCode::INTERNAL_SERVER_ERROR,
AppError::DoMainNotSet => StatusCode::INTERNAL_SERVER_ERROR,
AppError::InternalError => StatusCode::INTERNAL_SERVER_ERROR,
AppError::InternalServerError(_) => {
StatusCode::INTERNAL_SERVER_ERROR
}
AppError::PermissionDenied => StatusCode::FORBIDDEN,
AppError::ProjectNotFound => StatusCode::NOT_FOUND,
AppError::NoPower => StatusCode::FORBIDDEN,
AppError::RoleParseError => StatusCode::BAD_REQUEST,
AppError::ProjectNameAlreadyExists => StatusCode::CONFLICT,
AppError::RepoNameAlreadyExists => StatusCode::CONFLICT,
AppError::AvatarUploadError(_) => StatusCode::BAD_REQUEST,
AppError::RepoNotFound => StatusCode::NOT_FOUND,
AppError::RepoForBidAccess => StatusCode::FORBIDDEN,
AppError::SerdeError(_) => StatusCode::BAD_REQUEST,
AppError::Io(_) => StatusCode::INTERNAL_SERVER_ERROR,
AppError::BadRequest(_) => StatusCode::BAD_REQUEST,
AppError::Forbidden(_) => StatusCode::FORBIDDEN,
AppError::Conflict(_) => StatusCode::CONFLICT,
AppError::NotFound(_) => StatusCode::NOT_FOUND,
AppError::InvalidResetToken => StatusCode::BAD_REQUEST,
AppError::ResetTokenExpired => StatusCode::BAD_REQUEST,
AppError::ResetTokenUsed => StatusCode::BAD_REQUEST,
AppError::IssueNotFound => StatusCode::NOT_FOUND,
AppError::LabelNotFound => StatusCode::NOT_FOUND,
AppError::MilestoneNotFound => StatusCode::NOT_FOUND,
AppError::PullRequestNotFound => StatusCode::NOT_FOUND,
AppError::CommentNotFound => StatusCode::NOT_FOUND,
AppError::GitRpcError(_) => StatusCode::INTERNAL_SERVER_ERROR,
AppError::AiError(_) => StatusCode::INTERNAL_SERVER_ERROR,
}
}
fn error_response(&self) -> HttpResponse {
let status = self.status_code();
let message = self.0.to_string();
HttpResponse::build(status)
.json(serde_json::json!({ "error": message }))
}
}