| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- use std::io;
- use actix_web::{HttpResponse, ResponseError, http::StatusCode};
- use serde::Serialize;
- use thiserror::Error;
- pub type AppResult<T> = Result<T, AppError>;
- #[derive(Debug, Error)]
- pub enum AppError {
- #[error("I/O error: {0}")]
- Io(#[from] io::Error),
- #[error("database error: {0}")]
- Db(#[from] rusqlite::Error),
- #[error("configuration parse error: {0}")]
- Config(toml::de::Error),
- #[error("validation error: {0}")]
- Validation(String),
- #[error("conflict: {0}")]
- Conflict(String),
- #[error("not found: {0}")]
- NotFound(String),
- #[error("unauthorized: {0}")]
- Unauthorized(String),
- #[error("forbidden: {0}")]
- Forbidden(String),
- #[error("git error: {0}")]
- Git(String),
- }
- #[derive(Serialize)]
- struct ErrorBody {
- code: &'static str,
- message: String,
- status: u16,
- }
- impl ResponseError for AppError {
- fn status_code(&self) -> StatusCode {
- match self {
- AppError::Validation(_) => StatusCode::BAD_REQUEST,
- AppError::Conflict(_) => StatusCode::CONFLICT,
- AppError::NotFound(_) => StatusCode::NOT_FOUND,
- AppError::Unauthorized(_) => StatusCode::UNAUTHORIZED,
- AppError::Forbidden(_) => StatusCode::FORBIDDEN,
- AppError::Io(_) | AppError::Db(_) | AppError::Config(_) | AppError::Git(_) => {
- StatusCode::INTERNAL_SERVER_ERROR
- }
- }
- }
- fn error_response(&self) -> HttpResponse {
- HttpResponse::build(self.status_code()).json(ErrorBody {
- code: self.code(),
- message: self.public_message(),
- status: self.status_code().as_u16(),
- })
- }
- }
- impl AppError {
- fn code(&self) -> &'static str {
- match self {
- AppError::Validation(_) => "validation_error",
- AppError::Conflict(_) => "conflict",
- AppError::NotFound(_) => "not_found",
- AppError::Unauthorized(_) => "unauthorized",
- AppError::Forbidden(_) => "forbidden",
- AppError::Io(_) | AppError::Db(_) | AppError::Config(_) | AppError::Git(_) => {
- "internal_error"
- }
- }
- }
- fn public_message(&self) -> String {
- match self {
- AppError::Validation(message)
- | AppError::Conflict(message)
- | AppError::NotFound(message)
- | AppError::Unauthorized(message)
- | AppError::Forbidden(message) => message.clone(),
- AppError::Io(_) | AppError::Db(_) | AppError::Config(_) | AppError::Git(_) => {
- "internal server error".to_string()
- }
- }
- }
- }
|