Moved to better error handling system

This commit is contained in:
xeovalyte 2025-02-07 09:03:51 +01:00
parent 35527cbeb7
commit f7b7ebbb1c
Signed by: xeovalyte
SSH Key Fingerprint: SHA256:GWI1hq+MNKR2UOcvk7n9tekASXT8vyazK7vDF9Xyciw
4 changed files with 64 additions and 35 deletions

View File

@ -51,7 +51,7 @@ where
}, },
}; };
Err(AuthError::Unexpected.into()) Err(AuthError::Unauthorized.into())
} }
} }

View File

@ -6,6 +6,7 @@ pub enum AuthError {
InvalidToken, InvalidToken,
Unexpected, Unexpected,
InvalidPassword, InvalidPassword,
Unauthorized,
} }
impl Display for AuthError { impl Display for AuthError {
@ -15,6 +16,7 @@ impl Display for AuthError {
Self::InvalidToken => write!(f, "{}", "Invalid token"), Self::InvalidToken => write!(f, "{}", "Invalid token"),
Self::Unexpected => write!(f, "{}", "Unexpected error"), Self::Unexpected => write!(f, "{}", "Unexpected error"),
Self::InvalidPassword => write!(f, "{}", "Password is incorrect"), Self::InvalidPassword => write!(f, "{}", "Password is incorrect"),
Self::Unauthorized => write!(f, "{}", "Authentication is required"),
} }
} }
} }

View File

@ -1,6 +1,9 @@
use std::collections::HashMap; use std::collections::HashMap;
use axum::{extract::State, Json}; use axum::{
extract::{FromRef, State},
Json,
};
use itertools::Itertools; use itertools::Itertools;
use sqlx::PgPool; use sqlx::PgPool;
@ -53,10 +56,13 @@ pub async fn migrate_confirm<'a>(
tracing::info!("Migration is confirmed"); tracing::info!("Migration is confirmed");
// TODO: Implement better error naming
let count = match body.trim().parse::<u32>() { let count = match body.trim().parse::<u32>() {
Ok(c) => c, Ok(c) => c,
Err(_) => return Err(crate::Error::NotFound), Err(_) => {
return Err(crate::Error::BadRequest {
expected: String::from("u32"),
})
}
}; };
let mut store = state.migration_store.lock().await; let mut store = state.migration_store.lock().await;

View File

@ -7,50 +7,71 @@ use axum::{
#[derive(thiserror::Error, Debug)] #[derive(thiserror::Error, Debug)]
pub enum Error { pub enum Error {
#[error("CSV error: {0}")] #[error(transparent)]
Csv(#[from] csv::Error), Csv(#[from] csv::Error),
#[error("Auth error: {0}")] #[error(transparent)]
Auth(#[from] crate::auth::AuthError), Auth(#[from] crate::auth::AuthError),
#[error("Database error: {0}")] #[error(transparent)]
Database(#[from] sqlx::Error), Sqlx(#[from] sqlx::Error),
#[error("Resource not found")] #[error("resource not found")]
NotFound, NotFound,
#[error("Invalid request, expected {expected:?}")]
BadRequest { expected: String },
}
#[derive(serde::Serialize)]
struct ErrorResponse {
code: &'static str,
description: String,
}
impl ErrorResponse {
fn new(code: &'static str, description: String) -> Self {
Self { code, description }
}
} }
impl IntoResponse for Error { impl IntoResponse for Error {
fn into_response(self) -> Response { fn into_response(self) -> Response {
tracing::error!("Error... {:?}", self); let (status_code, code) = match self {
Self::Sqlx(ref err_kind) => match err_kind {
sqlx::Error::RowNotFound => (StatusCode::NOT_FOUND, "DATABSE_ROW_NOT_FOUND"),
_ => (StatusCode::INTERNAL_SERVER_ERROR, "DATABASE_ERROR"),
},
let (status, error_message) = match self { Self::Csv(ref err_kind) => match err_kind.kind() {
Error::Auth(AuthError::NoPermssions) => { csv::ErrorKind::UnequalLengths { .. } => {
(StatusCode::UNAUTHORIZED, String::from("No permissions")) (StatusCode::BAD_REQUEST, "CSV_INPUT_INVALID")
} }
Error::Auth(AuthError::InvalidToken) => { _ => (StatusCode::INTERNAL_SERVER_ERROR, "CSV_ERROR"),
(StatusCode::BAD_REQUEST, String::from("Invalid token")) },
}
Error::Auth(AuthError::Unexpected) => ( Self::Auth(ref err_kind) => match err_kind {
StatusCode::INTERNAL_SERVER_ERROR, crate::auth::AuthError::NoPermssions => {
String::from("Unexpected error occured"), (StatusCode::FORBIDDEN, "AUTH_NO_PERMISSIONS")
), }
Error::Auth(AuthError::InvalidPassword) => ( crate::auth::AuthError::Unauthorized => {
StatusCode::INTERNAL_SERVER_ERROR, (StatusCode::UNAUTHORIZED, "AUTH_UNAUTHORIZED")
String::from("Invalid password"), }
), crate::auth::AuthError::InvalidToken => {
Error::Csv(err) => (StatusCode::BAD_REQUEST, err.to_string()), (StatusCode::BAD_REQUEST, "AUTH_INVALID_TOKEN")
Error::NotFound => ( }
StatusCode::BAD_REQUEST, crate::auth::AuthError::InvalidPassword => {
String::from("Could not find resource"), (StatusCode::BAD_REQUEST, "AUTH_INVALID_PASSWORD")
), }
Error::Database(err) => (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()), _ => (StatusCode::INTERNAL_SERVER_ERROR, "AUTH_ERROR"),
},
Self::BadRequest { .. } => (StatusCode::BAD_REQUEST, "INVALID_BODY"),
Self::NotFound => (StatusCode::NOT_FOUND, "NOT_FOUND"),
}; };
let body = Json(serde_json::json!({ let body = ErrorResponse::new(code, self.to_string());
"error": error_message
}));
(status, body).into_response() (status_code, Json(body)).into_response()
} }
} }