From 6308630b4b9f91b17ca5dcf92242aee38d46e52a Mon Sep 17 00:00:00 2001 From: nicekid1 <86746988+nicekid1@users.noreply.github.com> Date: Wed, 8 Jan 2025 15:04:20 +0330 Subject: [PATCH] Improve error handling structure in user module --- src/admin/admin.controller.ts | 1 - src/admin/admin.service.ts | 11 +-- src/users/users.controller.ts | 11 ++- src/users/users.service.ts | 130 +++++++++++++++++++++------------- 4 files changed, 96 insertions(+), 57 deletions(-) diff --git a/src/admin/admin.controller.ts b/src/admin/admin.controller.ts index 25bd7cc..3172954 100644 --- a/src/admin/admin.controller.ts +++ b/src/admin/admin.controller.ts @@ -1,6 +1,5 @@ import { Controller, Get, Post, Body, Request, Put, UseGuards } from "@nestjs/common"; import { AdminService } from "./admin.service"; -import { Admin } from "./entities/admin.entity"; import { CreateAdminDto } from "./dto/create-Admin.dto"; import { LoginAdminDto } from "./dto/login-Admin.dto"; import { UpdateUserDto } from "./dto/update-user.dto"; diff --git a/src/admin/admin.service.ts b/src/admin/admin.service.ts index c8d8b91..5e571a4 100644 --- a/src/admin/admin.service.ts +++ b/src/admin/admin.service.ts @@ -66,17 +66,20 @@ export class AdminService { } } //edit admin profile method - async editAdminProfile(userId: number, updateAdminDto: UpdateUserDto): Promise<{ message }> { + async editAdminProfile(userId: number, updateAdminDto: UpdateUserDto) { try { - const user = await this.adminModel.findOne({ where: { id: userId } }); + let user = await this.adminModel.findOne({ where: { id: userId } }); if (!user) { throw new Error("Admin not found"); } await user.update(updateAdminDto); - - return { message: "admin account updated successful" }; + user = await this.adminModel.findOne({ + where: { id: userId }, + attributes: { exclude: ["password"] }, + }); + return { message: "user account updated successful", user }; } catch (error) { throw new Error(`An error occurred while updating admin: ${error.message}`); } diff --git a/src/users/users.controller.ts b/src/users/users.controller.ts index 6fe56c7..ee851a8 100644 --- a/src/users/users.controller.ts +++ b/src/users/users.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Post, Body, UseGuards, Get, Request, Put } from "@nestjs/common"; +import { Controller, Post, Body, UseGuards, Get, Request, Put, Param } from "@nestjs/common"; import { UsersService } from "./users.service"; import { User } from "./entities/user.entity"; import { CreateUserDto } from "./dto/create-user.dto"; @@ -12,7 +12,7 @@ export class UsersController { constructor(private readonly usersService: UsersService) {} //register as user @Post("register") - async register(@Body() createUserDto: CreateUserDto): Promise { + async register(@Body() createUserDto: CreateUserDto): Promise<{message}> { return this.usersService.register(createUserDto); } //login as user @@ -31,7 +31,7 @@ export class UsersController { //edit user profile @UseGuards(JwtAuthGuard) @Put() - async editProfile(@Request() req, @Body() updateUserDto: UpdateUserDto): Promise { + async editProfile(@Request() req, @Body() updateUserDto: UpdateUserDto) { const userId = req.user.id; return this.usersService.editProfile(userId, updateUserDto); } @@ -41,4 +41,9 @@ export class UsersController { async findAll(): Promise { return this.usersService.findAll(); } + @UseGuards(RoleGuard) + @Get("users/:id") + async findSpecificUserInfoByUser(@Param("id") id): Promise { + return this.usersService.findSpecificUserInfoByUser(id); + } } diff --git a/src/users/users.service.ts b/src/users/users.service.ts index 3adb4e8..eac7538 100644 --- a/src/users/users.service.ts +++ b/src/users/users.service.ts @@ -1,4 +1,4 @@ -import { HttpException, HttpStatus, Injectable, UnauthorizedException, BadRequestException, NotFoundException } from "@nestjs/common"; +import { HttpException, HttpStatus, Injectable, UnauthorizedException, BadRequestException, NotFoundException, UseGuards } from "@nestjs/common"; import { InjectModel } from "@nestjs/sequelize"; import { User } from "./entities/user.entity"; import * as bcrypt from "bcrypt"; @@ -17,83 +17,115 @@ export class UsersService { ) {} // Register method - async register(createUserDto: CreateUserDto): Promise { + async register(createUserDto: CreateUserDto): Promise<{ message }> { try { createUserDto.password = await bcrypt.hash(createUserDto.password, parseInt(process.env.BCRYPT_SALT_ROUNDS || "10", 10)); - const userExists = await this.userModel.findOne({ where: { email: createUserDto.email }, }); if (userExists) { - throw new BadRequestException("Email already exists"); + throw new BadRequestException("Email is already registered."); } - const user = await this.userModel.create(createUserDto); - return user; + return { message: "user registered successful" }; } catch (error) { - throw new HttpException(`An error occurred: ${error.message}`, HttpStatus.INTERNAL_SERVER_ERROR); + if (error instanceof HttpException) { + throw error; + } + throw new HttpException("An unexpected error occurred. Please try again later.", HttpStatus.INTERNAL_SERVER_ERROR); } } - // Login method async login(loginUserDto: LoginUserDto): Promise<{ token: string }> { - const user = await this.userModel.findOne({ - where: { email: loginUserDto.email }, - }); - if (!user) { - throw new UnauthorizedException("Invalid email or password"); - } + try { + const user = await this.userModel.findOne({ + where: { email: loginUserDto.email }, + }); - const passwordMatch = await bcrypt.compare(loginUserDto.password, user.password); - if (!passwordMatch) { - throw new UnauthorizedException("Invalid email or password"); + if (!user) { + throw new UnauthorizedException("Invalid email or password."); + } + const passwordMatch = await bcrypt.compare(loginUserDto.password, user.password); + if (!passwordMatch) { + throw new UnauthorizedException("Invalid email or password."); + } + const token = this.jwtService.sign( + { id: user.id, role: user.role }, + { + secret: this.configService.get("JWT_SECRET"), + expiresIn: this.configService.get("JWT_EXPIRES") || "1h", + }, + ); + return { token }; + } catch (error) { + if (error instanceof HttpException) { + throw error; + } + throw new HttpException("An unexpected error occurred. Please try again later.", HttpStatus.INTERNAL_SERVER_ERROR); } - - const token = this.jwtService.sign( - { id: user.id,role:user.role }, - { - secret: this.configService.get("JWT_SECRET"), - expiresIn: this.configService.get("JWT_EXPIRES") || "1h", - }, - ); - - return { token }; } //get information user method async getProfile(userId: number): Promise { - const user = await this.userModel.findOne({ - where: { id: userId }, - attributes: { exclude: ["password"] }, - }); - - if (!user) { - throw new Error("User not found"); + try { + const user = await this.userModel.findOne({ + where: { id: userId }, + attributes: { exclude: ["password"] }, + }); + if (!user) { + throw new HttpException("User not found.", HttpStatus.NOT_FOUND); + } + return user; + } catch (error) { + throw new HttpException("An unexpected error occurred. Please try again later.", HttpStatus.INTERNAL_SERVER_ERROR); } - - return user; } //edit profile user method async editProfile(userId: number, updateUserDto: UpdateUserDto) { - const user = await this.userModel.findOne({ where: { id: userId } }); - - if (!user) { - throw new NotFoundException("User not found"); - } - - if (updateUserDto.password) { - updateUserDto.password = await bcrypt.hash(updateUserDto.password, 10); + try { + let user = await this.userModel.findOne({ where: { id: userId } }); + if (!user) { + throw new NotFoundException('User not found.'); + } + if (updateUserDto.password) { + updateUserDto.password = await bcrypt.hash(updateUserDto.password, 10); + } + await user.update(updateUserDto); + user = await this.userModel.findOne({ + where: { id: userId }, + attributes: { exclude: ['password'] }, + }); + return { message: 'User account updated successfully.', user }; + } catch (error) { + throw new HttpException( + 'An unexpected error occurred. Please try again later.', + HttpStatus.INTERNAL_SERVER_ERROR, + ); } - - await user.update(updateUserDto); - - return user; } //get users list async findAll(): Promise { try { return await this.userModel.findAll(); } catch (error) { - throw new Error("An error occurred while fetching users"); + throw new HttpException( + 'An unexpected error occurred while fetching users.', + HttpStatus.INTERNAL_SERVER_ERROR, + ); + } + } + //get users list + async findSpecificUserInfoByUser(userId: number): Promise { + try { + const user = await this.userModel.findByPk(userId); + if (!user) { + throw new HttpException('User not found.', HttpStatus.NOT_FOUND); + } + return user; + } catch (error) { + throw new HttpException( + 'An unexpected error occurred while fetching user information.', + HttpStatus.INTERNAL_SERVER_ERROR, + ); } } }