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

78
Cargo.lock generated
View file

@ -348,6 +348,17 @@ dependencies = [
"slab", "slab",
] ]
[[package]]
name = "getrandom"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]] [[package]]
name = "gimli" name = "gimli"
version = "0.27.3" version = "0.27.3"
@ -379,6 +390,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "heck"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
[[package]] [[package]]
name = "hermit-abi" name = "hermit-abi"
version = "0.3.1" version = "0.3.1"
@ -600,9 +617,11 @@ dependencies = [
"lazy-regex", "lazy-regex",
"serde", "serde",
"serde_json", "serde_json",
"strum_macros",
"tokio", "tokio",
"tower-cookies", "tower-cookies",
"tower-http", "tower-http",
"uuid",
] ]
[[package]] [[package]]
@ -841,6 +860,12 @@ version = "0.3.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964" checksum = "26072860ba924cbfa98ea39c8c19b4dd6a4a25423dbdf219c1eca91aa0cf6964"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.63" version = "1.0.63"
@ -875,6 +900,36 @@ dependencies = [
"proc-macro2", "proc-macro2",
] ]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]] [[package]]
name = "redox_syscall" name = "redox_syscall"
version = "0.3.5" version = "0.3.5"
@ -1131,6 +1186,19 @@ dependencies = [
"windows-sys 0.48.0", "windows-sys 0.48.0",
] ]
[[package]]
name = "strum_macros"
version = "0.25.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23dc1fa9ac9c169a78ba62f0b841814b7abae11bdd047b9c58f893439e309ea0"
dependencies = [
"heck",
"proc-macro2",
"quote",
"rustversion",
"syn",
]
[[package]] [[package]]
name = "syn" name = "syn"
version = "2.0.22" version = "2.0.22"
@ -1416,6 +1484,16 @@ dependencies = [
"percent-encoding", "percent-encoding",
] ]
[[package]]
name = "uuid"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79daa5ed5740825c40b389c5e50312b9c86df53fccd33f281df655642b43869d"
dependencies = [
"getrandom",
"rand",
]
[[package]] [[package]]
name = "vcpkg" name = "vcpkg"
version = "0.2.15" version = "0.2.15"

View file

@ -17,6 +17,8 @@ tower-cookies = "0.9"
# Others # Others
lazy-regex = "3" lazy-regex = "3"
async-trait = "0.1" async-trait = "0.1"
strum_macros = "0.25"
uuid = { version = "1", features = ["v4", "fast-rng"] }
[dev-dependencies] [dev-dependencies]
anyhow = "1" anyhow = "1"

View file

@ -3,7 +3,7 @@ use axum::response::{IntoResponse, Response};
pub type Result<T> = core::result::Result<T, Error>; pub type Result<T> = core::result::Result<T, Error>;
#[derive(Clone, Debug)] #[derive(Clone, Debug, strum_macros::AsRefStr)]
pub enum Error { pub enum Error {
LoginFail, LoginFail,
@ -16,11 +16,50 @@ pub enum Error {
PropertyDeleteFailIdNotFound { id: u64 }, 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 { impl IntoResponse for Error {
fn into_response(self) -> Response { fn into_response(self) -> Response {
println!("->> {:<12} - {self:?}", "INTO_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::{middleware, Json, Router};
use axum::Server; use axum::Server;
use serde::Deserialize; use serde::Deserialize;
use serde_json::json;
use tower_http::services::ServeDir; use tower_http::services::ServeDir;
use tower_cookies::CookieManagerLayer; use tower_cookies::CookieManagerLayer;
use uuid::Uuid;
mod ctx; mod ctx;
mod error; mod error;
@ -56,10 +58,35 @@ async fn main() -> Result<()>{
/// ///
/// * `res`: the response to map /// * `res`: the response to map
async fn main_response_mapper(res: Response) -> Response { 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!(); println!();
res error_response.unwrap_or(res)
} }
/// Serve static files /// Serve static files