feat(services-controllers): implement debug mode and refactor error handling
- Implement debug mode for logging in services and controllers. - Improve the precision of memory usage information in the app by rounding. - Refactor error handling in services, notably in user service register function for better error checking. - Include a condition in the AdminGuard validator to check if the token is valid. - Fix issue in auth controller that was misidentifying user registration error as a successful registration. - Refactor log display in Mysql service error throwing for better readability. - Refactor memory usage information display in app for better readability. These changes aim to improve the clarity of logs and accuracy of error reporting for a better debugging experience. The implementation of debug mode gives more control over the information displayed in the development phase. Several fixes in error handling also contribute to a more robust system. Signed-off-by: Mathis <yidhra@tuta.io>
This commit is contained in:
parent
cb41c68f77
commit
abaeafea8a
@ -43,7 +43,7 @@ try {
|
||||
app.use("/auth", AuthRouter);
|
||||
app.use("/catalog", CatalogRouter);
|
||||
app.use("/rent", RentRouter);
|
||||
logger.info("Routers loaded !\n");
|
||||
logger.info("Routers loaded !");
|
||||
} catch (err) {
|
||||
logger.error(err);
|
||||
throw null;
|
||||
@ -53,9 +53,9 @@ try {
|
||||
app.listen(process.env["APP_PORT"]);
|
||||
logger.info(
|
||||
`Server is running !\n >> Memory total: ${
|
||||
process.memoryUsage().rss / 1_000_000
|
||||
} Mio\n >> Memory heap usage: ${
|
||||
process.memoryUsage().heapUsed / 1_000_000
|
||||
Math.round(process.memoryUsage().rss / 1_000_000)
|
||||
} Mio\n >> Memory heap: ${
|
||||
Math.round(process.memoryUsage().heapUsed / 1_000_000)
|
||||
} Mio\n`,
|
||||
);
|
||||
} catch (error) {
|
||||
|
@ -6,6 +6,7 @@ import UserService from "@services/user.service";
|
||||
import { isEmail } from "@utils/validators/email";
|
||||
import type { Request, Response } from "express";
|
||||
import { Logger } from "tslog";
|
||||
import {isDebugMode} from "@utils/debugState";
|
||||
|
||||
const logger = new Logger({
|
||||
name: "AuthController",
|
||||
@ -61,8 +62,8 @@ async function registerUser(req: Request, res: Response): Promise<unknown> {
|
||||
message: "GDPR not accepted.",
|
||||
});
|
||||
}
|
||||
if (RegisterServiceResult.error === "exist") {
|
||||
logger.warn(`The user already exists (${req.ip})`);
|
||||
if (typeof RegisterServiceResult !== 'string' && RegisterServiceResult.error === 5) {
|
||||
logger.warn(`The user already exists (${sanitizeData.email})`);
|
||||
return res.type("application/json").status(400).json({
|
||||
error: RegisterServiceResult.error,
|
||||
message: "The user already exists.",
|
||||
@ -70,8 +71,8 @@ async function registerUser(req: Request, res: Response): Promise<unknown> {
|
||||
}
|
||||
|
||||
// SUCCESS
|
||||
logger.info(`User registered successfully (${sanitizeData.username})`);
|
||||
return res.type("application/json").status(201).json(RegisterServiceResult);
|
||||
//logger.info(`User registered successfully (${sanitizeData.username})`);
|
||||
return res.type("application/json").status(201).json({token:RegisterServiceResult});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -393,7 +394,7 @@ async function getSelf(req: Request, res: Response) {
|
||||
});
|
||||
}
|
||||
|
||||
logger.debug("\nController loaded.");
|
||||
if (isDebugMode()) logger.debug("\nController loaded.");
|
||||
|
||||
const AuthController = {
|
||||
register: registerUser,
|
||||
|
@ -3,6 +3,7 @@ import { Logger } from "tslog";
|
||||
|
||||
import type IDbBrand from "@interfaces/database/IDbBrand";
|
||||
import BrandService from "@services/brand.service";
|
||||
import {isDebugMode} from "@utils/debugState";
|
||||
//import {body} from "express-validator";
|
||||
|
||||
const logger = new Logger({
|
||||
@ -171,7 +172,7 @@ async function deleteBrand(req: Request, res: Response): Promise<Response> {
|
||||
|
||||
//TODO get models of the brand
|
||||
|
||||
logger.debug("\nController loaded.");
|
||||
if (isDebugMode()) logger.debug("\nController loaded.");
|
||||
|
||||
const BrandController = {
|
||||
create: createBrand,
|
||||
|
@ -2,6 +2,7 @@ import type IDbCategory from "@interfaces/database/IDbCategory";
|
||||
import CategoryService from "@services/category.service";
|
||||
import type { Request, Response } from "express";
|
||||
import { Logger } from "tslog";
|
||||
import {isDebugMode} from "@utils/debugState";
|
||||
//import {validationResult} from "express-validator";
|
||||
|
||||
const logger = new Logger({
|
||||
@ -177,7 +178,7 @@ async function getBySlugCategory(
|
||||
});
|
||||
}
|
||||
|
||||
logger.debug("\nController loaded.");
|
||||
if (isDebugMode()) logger.debug("\nController loaded.");
|
||||
|
||||
const CategoryController = {
|
||||
create: createCategory,
|
||||
|
@ -3,6 +3,7 @@ import CategoryService from "@services/category.service";
|
||||
import ModelService from "@services/model.service";
|
||||
import type { Request, Response } from "express";
|
||||
import { Logger } from "tslog";
|
||||
import {isDebugMode} from "@utils/debugState";
|
||||
//import {validationResult} from "express-validator";
|
||||
|
||||
const logger = new Logger({
|
||||
@ -131,7 +132,7 @@ async function deleteModel(req: Request, res: Response): Promise<Response> {
|
||||
|
||||
//TODO get model with vehicle available.
|
||||
|
||||
logger.debug("\nController loaded.");
|
||||
if (isDebugMode()) logger.debug("\nController loaded.");
|
||||
|
||||
const ModelController = {
|
||||
create: createModel,
|
||||
|
@ -2,6 +2,7 @@ import type IDbBrand from "@interfaces/database/IDbBrand";
|
||||
import MysqlService from "@services/mysql.service";
|
||||
import { Logger } from "tslog";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import {isDebugMode} from "@utils/debugState";
|
||||
|
||||
const DbHandler = new MysqlService.Handler("BrandService");
|
||||
const logger = new Logger({
|
||||
@ -168,7 +169,7 @@ async function deleteBrand(brandId: string): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
logger.debug("\nService loaded.");
|
||||
if (isDebugMode()) logger.debug("\nService loaded.");
|
||||
|
||||
const BrandService = {
|
||||
create: createBrand,
|
||||
|
@ -2,6 +2,7 @@ import type { IDbCategory } from "@interfaces/database/IDbCategory";
|
||||
import MysqlService from "@services/mysql.service";
|
||||
import { Logger } from "tslog";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import {isDebugMode} from "@utils/debugState";
|
||||
|
||||
const DbHandler = new MysqlService.Handler("CategoryService");
|
||||
const logger = new Logger({
|
||||
@ -127,7 +128,7 @@ async function deleteCategory(id: string): Promise<unknown> {
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("\nService loaded.");
|
||||
if (isDebugMode()) logger.debug("\nService loaded.");
|
||||
|
||||
const CategoryService = {
|
||||
create: createCategory,
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
jwtVerify,
|
||||
} from "jose";
|
||||
import { Logger } from "tslog";
|
||||
import {isDebugMode} from "@utils/debugState";
|
||||
|
||||
const logger = new Logger({
|
||||
name: "JwtService",
|
||||
@ -64,7 +65,7 @@ async function JwtSignService(
|
||||
.sign(new TextEncoder().encode(`${process.env["JWT_SECRET"]}`));
|
||||
}
|
||||
|
||||
logger.debug("\nService loaded.");
|
||||
if (isDebugMode()) logger.debug("\nService loaded.");
|
||||
|
||||
const JwtService = {
|
||||
verify: JwtVerifyService,
|
||||
|
@ -2,6 +2,7 @@ import type IDbModel from "@interfaces/database/IDbModel";
|
||||
import MysqlService from "@services/mysql.service";
|
||||
import { Logger } from "tslog";
|
||||
import { v4 as uuidv4 } from "uuid";
|
||||
import {isDebugMode} from "@utils/debugState";
|
||||
|
||||
const DbHandler = new MysqlService.Handler("ModelService");
|
||||
const logger = new Logger({
|
||||
@ -135,7 +136,7 @@ async function getAllModels(): Promise<IDbModel[] | null> {
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("\nService loaded.");
|
||||
if (isDebugMode()) logger.debug("\nService loaded.");
|
||||
|
||||
/**
|
||||
* ModelService is responsible for managing models.
|
||||
|
@ -12,7 +12,7 @@ import type { IDbVehicle } from "@interfaces/database/IDbVehicle";
|
||||
import type { IUserUpdate } from "@interfaces/services/IUserUpdate";
|
||||
import mysql, { type Connection, type ConnectionOptions } from "mysql2";
|
||||
import { Logger } from "tslog";
|
||||
import { v4 } from "uuid";
|
||||
import {isDebugMode} from "@utils/debugState";
|
||||
|
||||
const access: ConnectionOptions = {
|
||||
host: `${process.env["MYSQL_HOST"]}`,
|
||||
@ -35,10 +35,10 @@ class MysqlHandler {
|
||||
this.Connection = mysql.createConnection(access);
|
||||
this.Connection.connect((err) => {
|
||||
if (err) {
|
||||
this.Logger.error(`Error connecting to MySQL: ${err}`);
|
||||
this.Logger.error(`\n\n> Error connecting to MySQL: \n${err}\n`);
|
||||
process.exit(1);
|
||||
}
|
||||
this.Logger.info(
|
||||
if (isDebugMode()) this.Logger.debug(
|
||||
`\n\n> Connected to MySQL database (${access.database})\n`,
|
||||
);
|
||||
});
|
||||
@ -51,7 +51,7 @@ class MysqlHandler {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.Connection.query(queryString, (err, results) => {
|
||||
if (err) {
|
||||
this.Logger.error(`Error executing query: ${err}`);
|
||||
this.Logger.error(`\n\n> Error executing query: \n${err}\n`);
|
||||
reject(err);
|
||||
} else {
|
||||
resolve(results);
|
||||
@ -82,12 +82,12 @@ class MysqlHandler {
|
||||
(key: string) => `${key}`,
|
||||
);
|
||||
const values = Object.values(data.values).map((val) => val);
|
||||
this.Logger.debug(
|
||||
if (isDebugMode()) this.Logger.debug(
|
||||
`\n\n>-> Factorized ${_sqlQueryKeys.length} keys for a prepare Query.\n>-> Action: ${data.actionName}\n`,
|
||||
);
|
||||
const sqlQueryKeys = _sqlQueryKeys.join(", ");
|
||||
if (_id && _id.length > 2) {
|
||||
this.Logger.trace(`Id post-pushed in factorized data`);
|
||||
if (isDebugMode()) this.Logger.trace(`\n\n> Id post-pushed in factorized data.\n ${_id}`);
|
||||
values.push(_id);
|
||||
}
|
||||
|
||||
@ -176,19 +176,6 @@ const MySqlService = {
|
||||
if (!data.id) return reject("Id is undefined");
|
||||
if (data.id.length !== 36) return reject("Id invalid");
|
||||
|
||||
// const _values = [
|
||||
// data.id,
|
||||
// data.username,
|
||||
// data.firstname,
|
||||
// data.lastname,
|
||||
// data.dob,
|
||||
// data.email,
|
||||
// data.is_mail_verified,
|
||||
// data.is_admin,
|
||||
// data.gdpr,
|
||||
// data.hash,
|
||||
// ];
|
||||
|
||||
handler
|
||||
.factorize({
|
||||
values: data,
|
||||
|
@ -7,6 +7,7 @@ import JwtService from "@services/jwt.service";
|
||||
import MySqlService from "@services/mysql.service";
|
||||
import { Logger } from "tslog";
|
||||
import { v4 } from "uuid";
|
||||
import {isDebugMode} from "@utils/debugState";
|
||||
|
||||
const logger = new Logger({
|
||||
name: "UserService",
|
||||
@ -63,14 +64,19 @@ async function getUserFromIdService(id: string): Promise<IDbUser | ISError> {
|
||||
};
|
||||
}
|
||||
const dbUser = await MySqlService.User.getById(DbHandler, id);
|
||||
if (dbUser === undefined) {
|
||||
if (dbUser.length === 0) {
|
||||
logger.info(`User not found (${id})`);
|
||||
return {
|
||||
error: ErrorType.NotFound,
|
||||
message: "The user was not found.",
|
||||
};
|
||||
}
|
||||
return dbUser;
|
||||
const firstUser = dbUser[0];
|
||||
if (firstUser) return firstUser;
|
||||
return {
|
||||
error: ErrorType.ServiceError,
|
||||
message: "No user found.",
|
||||
};
|
||||
} catch (err) {
|
||||
return {
|
||||
error: ErrorType.DatabaseError,
|
||||
@ -123,13 +129,7 @@ async function register(inputData: IReqRegister): Promise<ISError | string> {
|
||||
const dbUserIfExist: IDbUser | ISError = await getUserByEmail(
|
||||
inputData.email,
|
||||
);
|
||||
if ("error" in dbUserIfExist) {
|
||||
return {
|
||||
error: dbUserIfExist.error,
|
||||
message: dbUserIfExist.message,
|
||||
};
|
||||
}
|
||||
if (dbUserIfExist.id) {
|
||||
if ("username" in dbUserIfExist) {
|
||||
logger.info(
|
||||
`\n\n> User already exist for email "${inputData.email}".\n(${dbUserIfExist.username}::${dbUserIfExist.id})\n`,
|
||||
);
|
||||
@ -152,7 +152,7 @@ async function register(inputData: IReqRegister): Promise<ISError | string> {
|
||||
is_admin: false,
|
||||
is_email_verified: false,
|
||||
});
|
||||
if ("error" in NewUser || NewUser.affectedRows === 0) {
|
||||
if ("error" in NewUser && NewUser.affectedRows === 0) {
|
||||
return {
|
||||
error: ErrorType.DatabaseError,
|
||||
message: "Error when inserting user in database.",
|
||||
@ -326,7 +326,7 @@ async function deleteUserService(targetId) {
|
||||
}
|
||||
}
|
||||
|
||||
logger.debug("\nService loaded.");
|
||||
if (isDebugMode()) logger.debug("\nService loaded.");
|
||||
|
||||
const UserService = {
|
||||
register: register,
|
||||
|
@ -33,7 +33,7 @@ async function AdminGuard(req: Request, res: Response, next: NextFunction) {
|
||||
|
||||
const token = await JwtService.verify(bearerToken);
|
||||
|
||||
if (token) {
|
||||
if (token && token.sub) {
|
||||
// @ts-ignore
|
||||
const isSourceAdmin = await MysqlService.User.getAdminStateForId(
|
||||
DbHandler,
|
||||
|
Loading…
x
Reference in New Issue
Block a user