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("/auth", AuthRouter);
|
||||||
app.use("/catalog", CatalogRouter);
|
app.use("/catalog", CatalogRouter);
|
||||||
app.use("/rent", RentRouter);
|
app.use("/rent", RentRouter);
|
||||||
logger.info("Routers loaded !\n");
|
logger.info("Routers loaded !");
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
logger.error(err);
|
logger.error(err);
|
||||||
throw null;
|
throw null;
|
||||||
@ -53,9 +53,9 @@ try {
|
|||||||
app.listen(process.env["APP_PORT"]);
|
app.listen(process.env["APP_PORT"]);
|
||||||
logger.info(
|
logger.info(
|
||||||
`Server is running !\n >> Memory total: ${
|
`Server is running !\n >> Memory total: ${
|
||||||
process.memoryUsage().rss / 1_000_000
|
Math.round(process.memoryUsage().rss / 1_000_000)
|
||||||
} Mio\n >> Memory heap usage: ${
|
} Mio\n >> Memory heap: ${
|
||||||
process.memoryUsage().heapUsed / 1_000_000
|
Math.round(process.memoryUsage().heapUsed / 1_000_000)
|
||||||
} Mio\n`,
|
} Mio\n`,
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -6,6 +6,7 @@ import UserService from "@services/user.service";
|
|||||||
import { isEmail } from "@utils/validators/email";
|
import { isEmail } from "@utils/validators/email";
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
|
import {isDebugMode} from "@utils/debugState";
|
||||||
|
|
||||||
const logger = new Logger({
|
const logger = new Logger({
|
||||||
name: "AuthController",
|
name: "AuthController",
|
||||||
@ -61,8 +62,8 @@ async function registerUser(req: Request, res: Response): Promise<unknown> {
|
|||||||
message: "GDPR not accepted.",
|
message: "GDPR not accepted.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (RegisterServiceResult.error === "exist") {
|
if (typeof RegisterServiceResult !== 'string' && RegisterServiceResult.error === 5) {
|
||||||
logger.warn(`The user already exists (${req.ip})`);
|
logger.warn(`The user already exists (${sanitizeData.email})`);
|
||||||
return res.type("application/json").status(400).json({
|
return res.type("application/json").status(400).json({
|
||||||
error: RegisterServiceResult.error,
|
error: RegisterServiceResult.error,
|
||||||
message: "The user already exists.",
|
message: "The user already exists.",
|
||||||
@ -70,8 +71,8 @@ async function registerUser(req: Request, res: Response): Promise<unknown> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// SUCCESS
|
// SUCCESS
|
||||||
logger.info(`User registered successfully (${sanitizeData.username})`);
|
//logger.info(`User registered successfully (${sanitizeData.username})`);
|
||||||
return res.type("application/json").status(201).json(RegisterServiceResult);
|
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 = {
|
const AuthController = {
|
||||||
register: registerUser,
|
register: registerUser,
|
||||||
|
@ -3,6 +3,7 @@ import { Logger } from "tslog";
|
|||||||
|
|
||||||
import type IDbBrand from "@interfaces/database/IDbBrand";
|
import type IDbBrand from "@interfaces/database/IDbBrand";
|
||||||
import BrandService from "@services/brand.service";
|
import BrandService from "@services/brand.service";
|
||||||
|
import {isDebugMode} from "@utils/debugState";
|
||||||
//import {body} from "express-validator";
|
//import {body} from "express-validator";
|
||||||
|
|
||||||
const logger = new Logger({
|
const logger = new Logger({
|
||||||
@ -171,7 +172,7 @@ async function deleteBrand(req: Request, res: Response): Promise<Response> {
|
|||||||
|
|
||||||
//TODO get models of the brand
|
//TODO get models of the brand
|
||||||
|
|
||||||
logger.debug("\nController loaded.");
|
if (isDebugMode()) logger.debug("\nController loaded.");
|
||||||
|
|
||||||
const BrandController = {
|
const BrandController = {
|
||||||
create: createBrand,
|
create: createBrand,
|
||||||
|
@ -2,6 +2,7 @@ import type IDbCategory from "@interfaces/database/IDbCategory";
|
|||||||
import CategoryService from "@services/category.service";
|
import CategoryService from "@services/category.service";
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
|
import {isDebugMode} from "@utils/debugState";
|
||||||
//import {validationResult} from "express-validator";
|
//import {validationResult} from "express-validator";
|
||||||
|
|
||||||
const logger = new Logger({
|
const logger = new Logger({
|
||||||
@ -177,7 +178,7 @@ async function getBySlugCategory(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("\nController loaded.");
|
if (isDebugMode()) logger.debug("\nController loaded.");
|
||||||
|
|
||||||
const CategoryController = {
|
const CategoryController = {
|
||||||
create: createCategory,
|
create: createCategory,
|
||||||
|
@ -3,6 +3,7 @@ import CategoryService from "@services/category.service";
|
|||||||
import ModelService from "@services/model.service";
|
import ModelService from "@services/model.service";
|
||||||
import type { Request, Response } from "express";
|
import type { Request, Response } from "express";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
|
import {isDebugMode} from "@utils/debugState";
|
||||||
//import {validationResult} from "express-validator";
|
//import {validationResult} from "express-validator";
|
||||||
|
|
||||||
const logger = new Logger({
|
const logger = new Logger({
|
||||||
@ -131,7 +132,7 @@ async function deleteModel(req: Request, res: Response): Promise<Response> {
|
|||||||
|
|
||||||
//TODO get model with vehicle available.
|
//TODO get model with vehicle available.
|
||||||
|
|
||||||
logger.debug("\nController loaded.");
|
if (isDebugMode()) logger.debug("\nController loaded.");
|
||||||
|
|
||||||
const ModelController = {
|
const ModelController = {
|
||||||
create: createModel,
|
create: createModel,
|
||||||
|
@ -2,6 +2,7 @@ import type IDbBrand from "@interfaces/database/IDbBrand";
|
|||||||
import MysqlService from "@services/mysql.service";
|
import MysqlService from "@services/mysql.service";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import {isDebugMode} from "@utils/debugState";
|
||||||
|
|
||||||
const DbHandler = new MysqlService.Handler("BrandService");
|
const DbHandler = new MysqlService.Handler("BrandService");
|
||||||
const logger = new Logger({
|
const logger = new Logger({
|
||||||
@ -168,7 +169,7 @@ async function deleteBrand(brandId: string): Promise<boolean> {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("\nService loaded.");
|
if (isDebugMode()) logger.debug("\nService loaded.");
|
||||||
|
|
||||||
const BrandService = {
|
const BrandService = {
|
||||||
create: createBrand,
|
create: createBrand,
|
||||||
|
@ -2,6 +2,7 @@ import type { IDbCategory } from "@interfaces/database/IDbCategory";
|
|||||||
import MysqlService from "@services/mysql.service";
|
import MysqlService from "@services/mysql.service";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import {isDebugMode} from "@utils/debugState";
|
||||||
|
|
||||||
const DbHandler = new MysqlService.Handler("CategoryService");
|
const DbHandler = new MysqlService.Handler("CategoryService");
|
||||||
const logger = new Logger({
|
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 = {
|
const CategoryService = {
|
||||||
create: createCategory,
|
create: createCategory,
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
jwtVerify,
|
jwtVerify,
|
||||||
} from "jose";
|
} from "jose";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
|
import {isDebugMode} from "@utils/debugState";
|
||||||
|
|
||||||
const logger = new Logger({
|
const logger = new Logger({
|
||||||
name: "JwtService",
|
name: "JwtService",
|
||||||
@ -64,7 +65,7 @@ async function JwtSignService(
|
|||||||
.sign(new TextEncoder().encode(`${process.env["JWT_SECRET"]}`));
|
.sign(new TextEncoder().encode(`${process.env["JWT_SECRET"]}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug("\nService loaded.");
|
if (isDebugMode()) logger.debug("\nService loaded.");
|
||||||
|
|
||||||
const JwtService = {
|
const JwtService = {
|
||||||
verify: JwtVerifyService,
|
verify: JwtVerifyService,
|
||||||
|
@ -2,6 +2,7 @@ import type IDbModel from "@interfaces/database/IDbModel";
|
|||||||
import MysqlService from "@services/mysql.service";
|
import MysqlService from "@services/mysql.service";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
|
import {isDebugMode} from "@utils/debugState";
|
||||||
|
|
||||||
const DbHandler = new MysqlService.Handler("ModelService");
|
const DbHandler = new MysqlService.Handler("ModelService");
|
||||||
const logger = new Logger({
|
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.
|
* 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 type { IUserUpdate } from "@interfaces/services/IUserUpdate";
|
||||||
import mysql, { type Connection, type ConnectionOptions } from "mysql2";
|
import mysql, { type Connection, type ConnectionOptions } from "mysql2";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
import { v4 } from "uuid";
|
import {isDebugMode} from "@utils/debugState";
|
||||||
|
|
||||||
const access: ConnectionOptions = {
|
const access: ConnectionOptions = {
|
||||||
host: `${process.env["MYSQL_HOST"]}`,
|
host: `${process.env["MYSQL_HOST"]}`,
|
||||||
@ -35,10 +35,10 @@ class MysqlHandler {
|
|||||||
this.Connection = mysql.createConnection(access);
|
this.Connection = mysql.createConnection(access);
|
||||||
this.Connection.connect((err) => {
|
this.Connection.connect((err) => {
|
||||||
if (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);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
this.Logger.info(
|
if (isDebugMode()) this.Logger.debug(
|
||||||
`\n\n> Connected to MySQL database (${access.database})\n`,
|
`\n\n> Connected to MySQL database (${access.database})\n`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
@ -51,7 +51,7 @@ class MysqlHandler {
|
|||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
this.Connection.query(queryString, (err, results) => {
|
this.Connection.query(queryString, (err, results) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
this.Logger.error(`Error executing query: ${err}`);
|
this.Logger.error(`\n\n> Error executing query: \n${err}\n`);
|
||||||
reject(err);
|
reject(err);
|
||||||
} else {
|
} else {
|
||||||
resolve(results);
|
resolve(results);
|
||||||
@ -82,12 +82,12 @@ class MysqlHandler {
|
|||||||
(key: string) => `${key}`,
|
(key: string) => `${key}`,
|
||||||
);
|
);
|
||||||
const values = Object.values(data.values).map((val) => val);
|
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`,
|
`\n\n>-> Factorized ${_sqlQueryKeys.length} keys for a prepare Query.\n>-> Action: ${data.actionName}\n`,
|
||||||
);
|
);
|
||||||
const sqlQueryKeys = _sqlQueryKeys.join(", ");
|
const sqlQueryKeys = _sqlQueryKeys.join(", ");
|
||||||
if (_id && _id.length > 2) {
|
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);
|
values.push(_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,19 +176,6 @@ const MySqlService = {
|
|||||||
if (!data.id) return reject("Id is undefined");
|
if (!data.id) return reject("Id is undefined");
|
||||||
if (data.id.length !== 36) return reject("Id invalid");
|
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
|
handler
|
||||||
.factorize({
|
.factorize({
|
||||||
values: data,
|
values: data,
|
||||||
|
@ -7,6 +7,7 @@ import JwtService from "@services/jwt.service";
|
|||||||
import MySqlService from "@services/mysql.service";
|
import MySqlService from "@services/mysql.service";
|
||||||
import { Logger } from "tslog";
|
import { Logger } from "tslog";
|
||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
|
import {isDebugMode} from "@utils/debugState";
|
||||||
|
|
||||||
const logger = new Logger({
|
const logger = new Logger({
|
||||||
name: "UserService",
|
name: "UserService",
|
||||||
@ -63,14 +64,19 @@ async function getUserFromIdService(id: string): Promise<IDbUser | ISError> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
const dbUser = await MySqlService.User.getById(DbHandler, id);
|
const dbUser = await MySqlService.User.getById(DbHandler, id);
|
||||||
if (dbUser === undefined) {
|
if (dbUser.length === 0) {
|
||||||
logger.info(`User not found (${id})`);
|
logger.info(`User not found (${id})`);
|
||||||
return {
|
return {
|
||||||
error: ErrorType.NotFound,
|
error: ErrorType.NotFound,
|
||||||
message: "The user was not found.",
|
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) {
|
} catch (err) {
|
||||||
return {
|
return {
|
||||||
error: ErrorType.DatabaseError,
|
error: ErrorType.DatabaseError,
|
||||||
@ -123,13 +129,7 @@ async function register(inputData: IReqRegister): Promise<ISError | string> {
|
|||||||
const dbUserIfExist: IDbUser | ISError = await getUserByEmail(
|
const dbUserIfExist: IDbUser | ISError = await getUserByEmail(
|
||||||
inputData.email,
|
inputData.email,
|
||||||
);
|
);
|
||||||
if ("error" in dbUserIfExist) {
|
if ("username" in dbUserIfExist) {
|
||||||
return {
|
|
||||||
error: dbUserIfExist.error,
|
|
||||||
message: dbUserIfExist.message,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (dbUserIfExist.id) {
|
|
||||||
logger.info(
|
logger.info(
|
||||||
`\n\n> User already exist for email "${inputData.email}".\n(${dbUserIfExist.username}::${dbUserIfExist.id})\n`,
|
`\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_admin: false,
|
||||||
is_email_verified: false,
|
is_email_verified: false,
|
||||||
});
|
});
|
||||||
if ("error" in NewUser || NewUser.affectedRows === 0) {
|
if ("error" in NewUser && NewUser.affectedRows === 0) {
|
||||||
return {
|
return {
|
||||||
error: ErrorType.DatabaseError,
|
error: ErrorType.DatabaseError,
|
||||||
message: "Error when inserting user in database.",
|
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 = {
|
const UserService = {
|
||||||
register: register,
|
register: register,
|
||||||
|
@ -33,7 +33,7 @@ async function AdminGuard(req: Request, res: Response, next: NextFunction) {
|
|||||||
|
|
||||||
const token = await JwtService.verify(bearerToken);
|
const token = await JwtService.verify(bearerToken);
|
||||||
|
|
||||||
if (token) {
|
if (token && token.sub) {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
const isSourceAdmin = await MysqlService.User.getAdminStateForId(
|
const isSourceAdmin = await MysqlService.User.getAdminStateForId(
|
||||||
DbHandler,
|
DbHandler,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user