feat: enhance user creation error handling with specific messages for existing usernames and internal server errors

This commit is contained in:
Mika Bomm 2025-06-23 14:41:08 +02:00
parent 68119ba4de
commit d654ba0f0f
2 changed files with 23 additions and 3 deletions

View file

@ -1,5 +1,6 @@
use crate::{Database, db::entity, error::ApiError}; use crate::{Database, db::entity, error::ApiError};
use actix_web::{Responder, delete, get, post, put, web}; use actix_web::{Responder, delete, get, post, put, web};
use actix_web::error::ErrorInternalServerError;
use serde::Deserialize; use serde::Deserialize;
use utoipa::ToSchema; use utoipa::ToSchema;
use validator::Validate; use validator::Validate;
@ -90,11 +91,24 @@ async fn create_user(
user: web::Json<CreateUser>, user: web::Json<CreateUser>,
) -> Result<web::Json<entity::user::Model>, ApiError> { ) -> Result<web::Json<entity::user::Model>, ApiError> {
let user = user.into_inner(); let user = user.into_inner();
user.validate()
.map_err(|e| ApiError::BadRequest(format!("\nValidation error: {}", e)))?;
let username = user.username.clone();
let result = db let result = db
.create_user(user.name, user.username, user.password) .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( #[utoipa::path(

View file

@ -1,3 +1,4 @@
use std::fmt::{Display, Formatter};
use actix_web::{HttpResponse, ResponseError, http::StatusCode}; use actix_web::{HttpResponse, ResponseError, http::StatusCode};
use sea_orm::TransactionError; use sea_orm::TransactionError;
use serde::Serialize; use serde::Serialize;
@ -22,8 +23,11 @@ pub enum ApiError {
SessionInsertError(#[from] actix_session::SessionInsertError), SessionInsertError(#[from] actix_session::SessionInsertError),
#[error("Already logged in")] #[error("Already logged in")]
AlreadyLoggedIn, AlreadyLoggedIn,
#[error("User with username - {0} - already exists")]
UserAlreadyExists(String),
#[error("Internal Server Error for endpoint: {0}")]
InternalServerError(String)
} }
impl ResponseError for ApiError { impl ResponseError for ApiError {
fn status_code(&self) -> StatusCode { fn status_code(&self) -> StatusCode {
match self { match self {
@ -35,6 +39,8 @@ impl ResponseError for ApiError {
ApiError::Argon2Error(..) => StatusCode::INTERNAL_SERVER_ERROR, ApiError::Argon2Error(..) => StatusCode::INTERNAL_SERVER_ERROR,
ApiError::SessionInsertError(..) => StatusCode::INTERNAL_SERVER_ERROR, ApiError::SessionInsertError(..) => StatusCode::INTERNAL_SERVER_ERROR,
ApiError::AlreadyLoggedIn => StatusCode::CONFLICT, ApiError::AlreadyLoggedIn => StatusCode::CONFLICT,
ApiError::UserAlreadyExists(..) => StatusCode::CONFLICT,
ApiError::InternalServerError(..) => StatusCode::INTERNAL_SERVER_ERROR,
} }
} }