diff options
Diffstat (limited to 'src/errors.rs')
-rw-r--r-- | src/errors.rs | 80 |
1 files changed, 80 insertions, 0 deletions
diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..ee3ca71 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,80 @@ +use actix_web::{error::ResponseError, http::StatusCode, HttpResponse}; +use deadpool_postgres::PoolError; +use serde::Serialize; +use std::fmt; +use tokio_postgres::error::Error; + +#[derive(Debug)] +pub enum AppErrorType { + DbError, + NotFoundError, +} + +#[derive(Debug)] +pub struct AppError { + pub message: Option<String>, + pub cause: Option<String>, + pub error_type: AppErrorType, +} + +impl AppError { + pub fn message(&self) -> String { + match &*self { + AppError { + message: Some(message), + .. + } => message.clone(), + AppError { + message: None, + error_type: AppErrorType::NotFoundError, + .. + } => "The requested item was not found".to_string(), + _ => "An unexpected error has occurred".to_string(), + } + } +} + +impl From<PoolError> for AppError { + fn from(error: PoolError) -> AppError { + AppError { + message: None, + cause: Some(error.to_string()), + error_type: AppErrorType::DbError, + } + } +} + +impl From<Error> for AppError { + fn from(error: Error) -> AppError { + AppError { + message: None, + cause: Some(error.to_string()), + error_type: AppErrorType::DbError, + } + } +} + +impl fmt::Display for AppError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { + write!(f, "{:?}", self) + } +} + +#[derive(Serialize)] +pub struct AppErrorResponse { + pub error: String, +} + +impl ResponseError for AppError { + fn status_code(&self) -> StatusCode { + match self.error_type { + AppErrorType::DbError => StatusCode::INTERNAL_SERVER_ERROR, + AppErrorType::NotFoundError => StatusCode::NOT_FOUND, + } + } + fn error_response(&self) -> HttpResponse { + HttpResponse::build(self.status_code()).json(AppErrorResponse { + error: self.message(), + }) + } +} |