diff options
author | Toby Vincent <tobyv@tobyvin.dev> | 2024-03-26 21:04:02 -0500 |
---|---|---|
committer | Toby Vincent <tobyv@tobyvin.dev> | 2024-03-26 21:04:02 -0500 |
commit | ce961ca85ba96813ccdca9be1d18ee11e4e0d25c (patch) | |
tree | 4e368e35c275ea1be97473ae69aa052f4a0e98a2 /src/error.rs | |
parent | fd1447999d9665866d65002b2c2317b8b150225f (diff) |
feat: add user database and registration
Diffstat (limited to 'src/error.rs')
-rw-r--r-- | src/error.rs | 75 |
1 files changed, 49 insertions, 26 deletions
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<T, E = Error> = std::result::Result<T, E>; #[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() } } |