Skip to content

Commit cc5ed7f

Browse files
committed
Improve patterns on backend-javascript
1 parent 6a3bbab commit cc5ed7f

File tree

1 file changed

+84
-12
lines changed

1 file changed

+84
-12
lines changed

backend-javascript/src/modules/person/person.controller.js

Lines changed: 84 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ import { HTTP_STATUS } from '../../shared/constants/http/http-status.js';
22
import { ITEM_CONSTANTS } from './person.constant.js';
33
import { validateItem } from './person.schema.js';
44

5+
6+
const validatePositiveInteger = (value, fieldName = 'ID') => {
7+
const parsed = parseInt(value);
8+
if (isNaN(parsed) || parsed <= 0) {
9+
throw new Error(`Invalid ${fieldName} parameter. Must be a positive integer.`);
10+
}
11+
return parsed;
12+
};
13+
514
class Controller {
615
constructor(service) {
716
this.service = service;
@@ -21,11 +30,27 @@ class Controller {
2130

2231
getItemById = async (req, res, next) => {
2332
try {
24-
const result = await this.service.getItemById(parseInt(req.params.id));
25-
res.locals = { data: result, statusCode: HTTP_STATUS.OK };
33+
const id = validatePositiveInteger(req.params.id);
2634

35+
const result = await this.service.getItemById(id);
36+
res.locals = { data: result, statusCode: HTTP_STATUS.OK };
2737
return next();
38+
2839
} catch (error) {
40+
if (error.message.includes('Invalid') && error.message.includes('parameter')) {
41+
return next({
42+
statusCode: HTTP_STATUS.BAD_REQUEST,
43+
message: error.message,
44+
context: `${req.method} ${req.originalUrl}`,
45+
details: {
46+
path: req.originalUrl,
47+
errorCode: HTTP_STATUS.BAD_REQUEST,
48+
timestamp: new Date().toISOString(),
49+
receivedId: req.params.id
50+
}
51+
});
52+
}
53+
2954
if (error.message === ITEM_CONSTANTS.NOT_FOUND) {
3055
return next({
3156
statusCode: HTTP_STATUS.NOT_FOUND,
@@ -48,7 +73,6 @@ class Controller {
4873
validateItem(req.body);
4974
const result = await this.service.createItem(req.body);
5075
res.locals = { data: result, statusCode: HTTP_STATUS.CREATED };
51-
5276
return next();
5377
} catch (error) {
5478
if (error.message === ITEM_CONSTANTS.ALREADY_EXISTS) {
@@ -57,44 +81,92 @@ class Controller {
5781
if (error.name === 'ValidationError') {
5882
return next({ statusCode: HTTP_STATUS.BAD_REQUEST, message: error.message });
5983
}
60-
6184
return next(error);
6285
}
6386
};
6487

6588
updateItem = async (req, res, next) => {
6689
try {
90+
const id = validatePositiveInteger(req.params.id);
91+
6792
validateItem(req.body);
68-
const result = await this.service.updateItem(parseInt(req.params.id), req.body);
93+
const result = await this.service.updateItem(id, req.body);
6994
res.locals = { data: result, statusCode: HTTP_STATUS.OK };
70-
7195
return next();
96+
7297
} catch (error) {
98+
if (error.message.includes('Invalid') && error.message.includes('parameter')) {
99+
return next({
100+
statusCode: HTTP_STATUS.BAD_REQUEST,
101+
message: error.message,
102+
context: `${req.method} ${req.originalUrl}`,
103+
details: {
104+
path: req.originalUrl,
105+
errorCode: HTTP_STATUS.BAD_REQUEST,
106+
timestamp: new Date().toISOString(),
107+
receivedId: req.params.id
108+
}
109+
});
110+
}
111+
73112
if (error.message === ITEM_CONSTANTS.NOT_FOUND) {
74-
return next({ statusCode: HTTP_STATUS.NOT_FOUND, message: error.message });
113+
return next({
114+
statusCode: HTTP_STATUS.NOT_FOUND,
115+
message: error.message,
116+
context: `${req.method} ${req.originalUrl}`,
117+
details: {
118+
path: req.originalUrl,
119+
errorCode: HTTP_STATUS.NOT_FOUND,
120+
timestamp: new Date().toISOString(),
121+
}
122+
});
75123
}
76124
if (error.name === 'ValidationError') {
77125
return next({ statusCode: HTTP_STATUS.BAD_REQUEST, message: error.message });
78126
}
79-
80127
return next(error);
81128
}
82129
};
83130

84131
deleteItem = async (req, res, next) => {
85132
try {
86-
const result = await this.service.deleteItem(parseInt(req.params.id));
87-
res.locals = { data: result, statusCode: HTTP_STATUS.OK };
133+
const id = validatePositiveInteger(req.params.id);
88134

135+
const result = await this.service.deleteItem(id);
136+
res.locals = { data: result, statusCode: HTTP_STATUS.OK };
89137
return next();
138+
90139
} catch (error) {
91-
if (error.message === ITEM_CONSTANTS.NOT_FOUND) {
92-
return next({ statusCode: HTTP_STATUS.NOT_FOUND, message: error.message });
140+
if (error.message.includes('Invalid') && error.message.includes('parameter')) {
141+
return next({
142+
statusCode: HTTP_STATUS.BAD_REQUEST,
143+
message: error.message,
144+
context: `${req.method} ${req.originalUrl}`,
145+
details: {
146+
path: req.originalUrl,
147+
errorCode: HTTP_STATUS.BAD_REQUEST,
148+
timestamp: new Date().toISOString(),
149+
receivedId: req.params.id
150+
}
151+
});
93152
}
94153

154+
if (error.message === ITEM_CONSTANTS.NOT_FOUND) {
155+
return next({
156+
statusCode: HTTP_STATUS.NOT_FOUND,
157+
message: error.message,
158+
context: `${req.method} ${req.originalUrl}`,
159+
details: {
160+
path: req.originalUrl,
161+
errorCode: HTTP_STATUS.NOT_FOUND,
162+
timestamp: new Date().toISOString(),
163+
}
164+
});
165+
}
95166
return next(error);
96167
}
97168
};
169+
98170
}
99171

100172
export default Controller;

0 commit comments

Comments
 (0)