feat: client and server errors

This commit is contained in:
Sandro Eiler 2023-10-16 14:38:15 +02:00
parent bcdd397033
commit 0f0f7f3961
4 changed files with 151 additions and 5 deletions

View file

@ -3,7 +3,7 @@ use axum::response::{IntoResponse, Response};
pub type Result<T> = core::result::Result<T, Error>;
#[derive(Clone, Debug)]
#[derive(Clone, Debug, strum_macros::AsRefStr)]
pub enum Error {
LoginFail,
@ -16,11 +16,50 @@ pub enum Error {
PropertyDeleteFailIdNotFound { id: u64 },
}
/// FIXME: return different status codes for different errors
impl Error {
pub fn client_status_and_error(&self) -> (StatusCode, ClientError) {
match self {
// -- Login.
Self::LoginFail => (StatusCode::UNAUTHORIZED, ClientError::LOGIN_FAIL),
// -- Auth.
Self::AuthFailNoAuthTokenCookie
| Self::AuthFailTokenWrongFormat
| Self::AuthFailCtxNotInRequestExt => (StatusCode::FORBIDDEN, ClientError::NO_AUTH),
// -- Model.
Self::PropertyDeleteFailIdNotFound { .. } => {
(StatusCode::BAD_REQUEST, ClientError::INVALID_PARAMS)
}
// -- Fallback.
_ => (
StatusCode::INTERNAL_SERVER_ERROR,
ClientError::SERVICE_ERROR,
),
}
}
}
impl IntoResponse for Error {
fn into_response(self) -> Response {
println!("->> {:<12} - {self:?}", "INTO_RESPONSE");
(StatusCode::INTERNAL_SERVER_ERROR, "UNHANDLED_CLIENT_ERROR").into_response()
// Create a placeholder Axum response.
let mut response = StatusCode::INTERNAL_SERVER_ERROR.into_response();
// Insert the Error into the response.
response.extensions_mut().insert(self);
response
}
}
#[derive(Debug, strum_macros::AsRefStr)]
#[allow(non_camel_case_types)]
pub enum ClientError {
LOGIN_FAIL,
NO_AUTH,
INVALID_PARAMS,
SERVICE_ERROR,
}

View file

@ -13,8 +13,10 @@ use axum::routing::{get, get_service};
use axum::{middleware, Json, Router};
use axum::Server;
use serde::Deserialize;
use serde_json::json;
use tower_http::services::ServeDir;
use tower_cookies::CookieManagerLayer;
use uuid::Uuid;
mod ctx;
mod error;
@ -56,10 +58,35 @@ async fn main() -> Result<()>{
///
/// * `res`: the response to map
async fn main_response_mapper(res: Response) -> Response {
println!("->> {:<12} - main_response_mapper", "HANDLER");
println!("->> {:<12} - main_response_mapper", "RES_MAPPER");
let uuid = Uuid::new_v4();
// -- Get the eventual response error.
let service_error = res.extensions().get::<Error>();
let client_status_error = service_error.map(|se| se.client_status_and_error());
// -- If client error, build the new response
let error_response = client_status_error
.as_ref()
.map(|(status_code, client_error)| {
let client_error_body = json!({
"error": {
"type": client_error.as_ref(),
"req_uuid": uuid.to_string(),
}
});
println!(" ->> client_error_body: {client_error_body}");
// Build the new response from the client error body.
(*status_code, Json(client_error_body)).into_response()
});
// -- TODO: Build and log the server log line.
println!(" ->> server log line - {uuid} - Error: {service_error:?}");
println!();
res
error_response.unwrap_or(res)
}
/// Serve static files