diff options
author | Toby Vincent <tobyv@tobyvin.dev> | 2024-04-11 23:43:55 -0500 |
---|---|---|
committer | Toby Vincent <tobyv@tobyvin.dev> | 2024-04-11 23:57:02 -0500 |
commit | b26d3c09eaec958c75931cc126367d4124cbffad (patch) | |
tree | 04eb1039b1f4646d84356a3b1779b24701609417 /src/api | |
parent | a20f3667a88affa0498e564cea17e9e795162bb8 (diff) |
refactor: improve error handling and layout
Diffstat (limited to 'src/api')
-rw-r--r-- | src/api/error.rs | 37 | ||||
-rw-r--r-- | src/api/users.rs | 6 |
2 files changed, 41 insertions, 2 deletions
diff --git a/src/api/error.rs b/src/api/error.rs new file mode 100644 index 0000000..4088b9b --- /dev/null +++ b/src/api/error.rs @@ -0,0 +1,37 @@ +#[derive(thiserror::Error, Debug)] +pub enum Error { + #[error("Database error: {0}")] + Sqlx(#[from] sqlx::Error), + + #[error("User not found")] + UserNotFound, + + #[error("Invalid user token")] + InvalidToken, + + #[error("User with that email already exists")] + EmailExists, + + #[error("Invalid email: {0}")] + EmailInvalid(#[from] email_address::Error), + + #[error("Authentication error: {0}")] + Auth(#[from] crate::auth::error::Error), +} + +impl axum::response::IntoResponse for Error { + fn into_response(self) -> axum::response::Response { + use axum::http::StatusCode; + + let status = match self { + Self::UserNotFound => StatusCode::NOT_FOUND, + Self::EmailExists => StatusCode::CONFLICT, + Self::EmailInvalid(_) => StatusCode::UNPROCESSABLE_ENTITY, + Self::InvalidToken => StatusCode::UNAUTHORIZED, + Self::Sqlx(_) => StatusCode::INTERNAL_SERVER_ERROR, + Self::Auth(err) => return err.into_response(), + }; + + (status, self.to_string()).into_response() + } +} diff --git a/src/api/users.rs b/src/api/users.rs index 3eb7e89..7a9bb6e 100644 --- a/src/api/users.rs +++ b/src/api/users.rs @@ -11,7 +11,9 @@ use sqlx::FromRow; use time::OffsetDateTime; use uuid::Uuid; -use crate::{auth::AccessClaims, state::AppState, Error}; +use crate::{auth::AccessClaims, state::AppState}; + +use super::error::Error; pub fn router() -> Resource<AppState> { Resource::named("users").create(create).show(show) @@ -222,7 +224,7 @@ mod tests { let response = router.oneshot(request).await?; - assert_eq!(StatusCode::UNAUTHORIZED, response.status()); + assert_eq!(StatusCode::UNPROCESSABLE_ENTITY, response.status()); Ok(()) } |