From ce961ca85ba96813ccdca9be1d18ee11e4e0d25c Mon Sep 17 00:00:00 2001 From: Toby Vincent Date: Tue, 26 Mar 2024 21:04:02 -0500 Subject: feat: add user database and registration --- src/error.rs | 75 +++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 26 deletions(-) (limited to 'src/error.rs') diff --git a/src/error.rs b/src/error.rs index a5b48ff..54075da 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,46 +1,69 @@ +use axum::{http::StatusCode, Json}; +use serde_json::json; + pub type Result = std::result::Result; #[derive(thiserror::Error, Debug)] pub enum Error { - #[error(transparent)] + #[error("IO error: {0}")] IO(#[from] std::io::Error), - #[error(transparent)] - TaskJoin(#[from] tokio::task::JoinError), + #[error("Env variable error: {0}")] + Env(#[from] dotenvy::Error), - #[error(transparent)] + #[error("Axum error: {0}")] Axum(#[from] axum::Error), - #[error(transparent)] + #[error("Http error: {0}")] + Http(#[from] axum::http::Error), + + #[error("Json error: {0}")] + Json(#[from] serde_json::Error), + + #[error("Database error: {0}")] Sqlx(#[from] sqlx::Error), - #[error(transparent)] + #[error("Migration error: {0}")] Migration(#[from] sqlx::migrate::MigrateError), - #[error("User not found: {0}")] - UserNotFound(uuid::Uuid), + #[error("Failed to hash password: {0}")] + PasswordHash(#[from] argon2::password_hash::Error), + + #[error("User not found")] + UserNotFound, + + #[error("User with that email already exists")] + EmailExists, + + #[error("Email is invalid")] + EmailInvalid, + + #[error("Password is invalid")] + PasswordInvalid, + + #[error("{0}")] + Other(String), +} + +impl From<&Error> for StatusCode { + fn from(value: &Error) -> Self { + match value { + Error::UserNotFound => StatusCode::NOT_FOUND, + Error::EmailExists => StatusCode::CONFLICT, + Error::EmailInvalid | Error::PasswordInvalid => StatusCode::UNPROCESSABLE_ENTITY, + _ => StatusCode::INTERNAL_SERVER_ERROR, + } + } } impl axum::response::IntoResponse for Error { fn into_response(self) -> axum::response::Response { - use axum::{http::StatusCode, Json}; - use serde_json::json; - - match self { - Error::UserNotFound(uuid) => ( - StatusCode::BAD_REQUEST, - Json(json!({ - "status": "fail", - "message": uuid, - })), - ), - err => ( - StatusCode::INTERNAL_SERVER_ERROR, - Json(json!({ - "error": err.to_string(), - })), - ), - } + // TODO: implement [rfc7807](https://www.rfc-editor.org/rfc/rfc7807.html) + + Json(json!({ + "status": StatusCode::from(&self).to_string(), + "detail": self.to_string(), + })) .into_response() } } -- cgit v1.2.3-70-g09d2