From d654ba0f0f8979faa0e36b7c1cd75f0bc3d0b969 Mon Sep 17 00:00:00 2001 From: Mika Bomm Date: Mon, 23 Jun 2025 14:41:08 +0200 Subject: [PATCH] feat: enhance user creation error handling with specific messages for existing usernames and internal server errors --- crates/backend/src/controller/user.rs | 18 ++++++++++++++++-- crates/backend/src/error.rs | 8 +++++++- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/crates/backend/src/controller/user.rs b/crates/backend/src/controller/user.rs index 3adee87..07da1cf 100644 --- a/crates/backend/src/controller/user.rs +++ b/crates/backend/src/controller/user.rs @@ -1,5 +1,6 @@ use crate::{Database, db::entity, error::ApiError}; use actix_web::{Responder, delete, get, post, put, web}; +use actix_web::error::ErrorInternalServerError; use serde::Deserialize; use utoipa::ToSchema; use validator::Validate; @@ -90,11 +91,24 @@ async fn create_user( user: web::Json, ) -> Result, ApiError> { let user = user.into_inner(); + user.validate() + .map_err(|e| ApiError::BadRequest(format!("\nValidation error: {}", e)))?; + + let username = user.username.clone(); let result = db .create_user(user.name, user.username, user.password) - .await?; + .await; - Ok(web::Json(result)) + match result { + Ok(result) => Ok(web::Json(result)), + Err(e) => { + if e.to_string().contains("user_username_key") { + Err(ApiError::UserAlreadyExists(username)) + } else { + Err(ApiError::InternalServerError("/user/ - create_user - Error: {e}".to_owned())) + } + } + } } #[utoipa::path( diff --git a/crates/backend/src/error.rs b/crates/backend/src/error.rs index 50f0872..f28151c 100644 --- a/crates/backend/src/error.rs +++ b/crates/backend/src/error.rs @@ -1,3 +1,4 @@ +use std::fmt::{Display, Formatter}; use actix_web::{HttpResponse, ResponseError, http::StatusCode}; use sea_orm::TransactionError; use serde::Serialize; @@ -22,8 +23,11 @@ pub enum ApiError { SessionInsertError(#[from] actix_session::SessionInsertError), #[error("Already logged in")] AlreadyLoggedIn, + #[error("User with username - {0} - already exists")] + UserAlreadyExists(String), + #[error("Internal Server Error for endpoint: {0}")] + InternalServerError(String) } - impl ResponseError for ApiError { fn status_code(&self) -> StatusCode { match self { @@ -35,6 +39,8 @@ impl ResponseError for ApiError { ApiError::Argon2Error(..) => StatusCode::INTERNAL_SERVER_ERROR, ApiError::SessionInsertError(..) => StatusCode::INTERNAL_SERVER_ERROR, ApiError::AlreadyLoggedIn => StatusCode::CONFLICT, + ApiError::UserAlreadyExists(..) => StatusCode::CONFLICT, + ApiError::InternalServerError(..) => StatusCode::INTERNAL_SERVER_ERROR, } }