summaryrefslogtreecommitdiff
path: root/src/errors.rs
diff options
context:
space:
mode:
authorSanto Cariotti <santo@dcariotti.me>2021-03-16 11:22:42 +0100
committerGitHub <noreply@github.com>2021-03-16 11:22:42 +0100
commitb950072a3109d2c13881611a3950baa191caf097 (patch)
treeccfc5c2c26c56a496d0f34b3f4db0965c713e7bb /src/errors.rs
parent48a9ac895b6e8b01622810ec4bf2f3a423426ca3 (diff)
parent6350610ef5f7d73680853d39898094f2bf15febb (diff)
Merge pull request #11 from gico-net/feat/add-repositories
Add CRUD for repository
Diffstat (limited to 'src/errors.rs')
-rw-r--r--src/errors.rs84
1 files changed, 84 insertions, 0 deletions
diff --git a/src/errors.rs b/src/errors.rs
new file mode 100644
index 0000000..8140cfe
--- /dev/null
+++ b/src/errors.rs
@@ -0,0 +1,84 @@
+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,
+ AuthorizationError,
+}
+
+#[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 detail: 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,
+ AppErrorType::AuthorizationError => StatusCode::UNAUTHORIZED,
+ }
+ }
+
+ /// Returns a JSON response with "detail" as key
+ fn error_response(&self) -> HttpResponse {
+ HttpResponse::build(self.status_code()).json(AppErrorResponse {
+ detail: self.message(),
+ })
+ }
+}