From 9fe3659375ed939028d9097a1a7ec7a029cf0fde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Brian=20Pina=20de=20S=C3=A1?= Date: Fri, 6 Aug 2021 19:14:11 -0300 Subject: [PATCH 1/2] refactor: create error classes and error middleware refactor:change error handling --- index.js | 2 + src/controllers/CampaignController.js | 125 ++++++---------- src/controllers/CategoryController.js | 30 ++-- src/controllers/EntityController.js | 81 +++-------- src/controllers/HelpController.js | 160 +++++---------------- src/controllers/HelpOfferController.js | 55 ++----- src/controllers/NotificationController.js | 21 +-- src/controllers/UserController.js | 104 ++++---------- src/repository/BaseRepository.js | 3 +- src/services/CampaignService.js | 7 +- src/services/CategoryService.js | 5 +- src/services/EntityService.js | 10 +- src/services/HelpOfferService.js | 9 +- src/services/HelpService.js | 63 ++++---- src/services/UserService.js | 13 +- src/utils/errorHandler.js | 65 +++++++++ src/validation/middlewares/authFirebase.js | 6 +- 17 files changed, 266 insertions(+), 493 deletions(-) create mode 100644 src/utils/errorHandler.js diff --git a/index.js b/index.js index 83a92a06..f8f2effa 100644 --- a/index.js +++ b/index.js @@ -18,6 +18,7 @@ app.use(express.json({ limit: '50mb' })); app.use(express.urlencoded({ limit: '50mb' })); setupWebsocket(server); const databaseConnect = require('./src/config/database'); +const { errorHandler } = require('./src/utils/errorHandler'); app.use(cors()); app.use(bodyParser.json()); @@ -26,6 +27,7 @@ databaseConnect(); dailySchedule(); setRoutes(app); +app.use(errorHandler); app.use(Sentry.Handlers.errorHandler()); server.listen(8000); diff --git a/src/controllers/CampaignController.js b/src/controllers/CampaignController.js index 8bba2160..44aee146 100644 --- a/src/controllers/CampaignController.js +++ b/src/controllers/CampaignController.js @@ -1,4 +1,5 @@ const CampaignService = require('../services/CampaignService'); +const { UnauthorizedError, BadRequestError } = require('../utils/errorHandler'); const saveError = require('../utils/ErrorHistory'); class CampaignController { @@ -7,70 +8,46 @@ class CampaignController { } async createCampaign(req, res) { - try { - const newCampaign = await this.CampaignService.createNewCampaign( - req.body, - ); - return res.json(newCampaign); - } catch (error) { - return res.status(400).json({ error: error.message }); - } + const newCampaign = await this.CampaignService.createNewCampaign( + req.body, + ); + return res.json(newCampaign); } async listCampaign(req, res) { - try { - const campaign = await this.CampaignService.listCampaign(); - return res.json(campaign); - } catch (error) { - return res.status(400).json(error); - } + const campaign = await this.CampaignService.listCampaign(); + return res.json(campaign); } - async getCampaignListByStatus(req, res, next) { + async getCampaignListByStatus(req, res) { const { userId } = req.params; const statusList = req.query.statusList.split(','); - try { - const result = await this.CampaignService.getCampaignListByStatus({ - userId, - statusList, - }); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.CampaignService.getCampaignListByStatus({ + userId, + statusList, + }); + return res.status(200).json(result); } async listCampaignByOwnerId(req, res) { const { ownerId } = req.params; - try { - const campaign = await this.CampaignService.listCampaignByOwnerId( - ownerId, - ); - return res.json(campaign); - } catch (error) { - return res.status(400).json(error); - } + if(!ownerId) throw new UnauthorizedError('No ownerId provided'); + const campaign = await this.CampaignService.listCampaignByOwnerId( + ownerId, + ); + return res.json(campaign); } - async deleteCampaignLogic(req, res, next) { + async deleteCampaignLogic(req, res) { const { id } = req.params; - try { - const result = await this.CampaignService.deleteCampaign(id); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + if(!id) throw new BadRequestError('No id provided'); + const result = await this.CampaignService.deleteCampaign(id); + res.status(200).json(result); } - async listCampaignNear(req, res, next) { + async listCampaignNear(req, res) { const except = !!req.query['id.except']; const helper = !!req.query['id.helper']; let temp = null; @@ -90,51 +67,29 @@ class CampaignController { ? req.query.coords.split(',').map((coord) => Number(coord)) : null; - try { - let result; - if (near) { - result = await this.CampaignService.getNearCampaignList( - coords, - except, - id, - categoryArray, - ); - } - res.status(200); - res.json(result); - next(); - } catch (err) { - console.log(err); - saveError(err); - res.status(400).json({ error: err.message }); - next(); + let result; + if (near) { + result = await this.CampaignService.getNearCampaignList( + coords, + except, + id, + categoryArray, + ); } + return res.status(200).json(result); } - async finishCampaign(req, res, next) { - const { id } = req.params; - try { - const result = await this.CampaignService.finishCampaign(id); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + async finishCampaign(req, res) { + if(!id) throw new BadRequestError('No id provided'); + const result = await this.CampaignService.finishCampaign(id); + return res.status(200).json(result); } - async getCampaignById(req, res, next) { + async getCampaignById(req, res) { const { id } = req.params; - try { - const result = await this.CampaignService.getCampaignById(id); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + if(!id) throw new BadRequestError('No id provided') + const result = await this.CampaignService.getCampaignById(id); + return res.status(200).json(result); } } diff --git a/src/controllers/CategoryController.js b/src/controllers/CategoryController.js index 2c78a30a..d444a0be 100644 --- a/src/controllers/CategoryController.js +++ b/src/controllers/CategoryController.js @@ -1,4 +1,5 @@ const CategoryService = require('../services/CategoryService'); +const { BadRequestError } = require('../utils/errorHandler'); const saveError = require('../utils/ErrorHistory'); class CategoryController { @@ -6,32 +7,17 @@ class CategoryController { this.CategoryService = new CategoryService(); } - async getCategoryById(req, res, next) { + async getCategoryById(req, res) { const { id } = req.params; - - try { - const result = await this.CategoryService.getCategoryByid(id); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + if(!id) throw new BadRequestError('No id provided'); + const result = await this.CategoryService.getCategoryByid(id); + return res.status(200).json(result); } - async getCategoryList(req, res, next) { + async getCategoryList(req, res) { const id = req.query.id || null; - - try { - const result = await this.CategoryService.getCategoryList(id); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.CategoryService.getCategoryList(id); + return res.status(200).json(result); } } diff --git a/src/controllers/EntityController.js b/src/controllers/EntityController.js index 19bab5cc..c4b0a7d9 100644 --- a/src/controllers/EntityController.js +++ b/src/controllers/EntityController.js @@ -6,7 +6,7 @@ class EntityController { this.entityService = new EntityService(); } - async createEntity(req, res, next) { + async createEntity(req, res) { const { latitude, longitude } = req.body; const location = { @@ -20,18 +20,11 @@ class EntityController { hasEntity: req.query.hasEntity === 'true', }; - try { - const result = await this.entityService.createEntity(data); - res.status(201).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.entityService.createEntity(data); + return res.status(201).json(result); } - async editEntityById(req, res, next) { + async editEntityById(req, res) { const data = { email: req.decodedToken.email, photo: req.body.photo, @@ -40,15 +33,8 @@ class EntityController { notificationToken: req.body.notificationToken, deviceId: req.body.deviceId, }; - try { - const result = await this.entityService.editEntityById(data); - res.status(200).json(result); - return next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - return next(); - } + const result = await this.entityService.editEntityById(data); + return res.status(200).json(result); } async editEntityAddressById(req, res, next) { @@ -61,29 +47,15 @@ class EntityController { complement: req.body.complement, }; - try { - const result = await this.entityService.editEntityAddressById(data); - res.status(200).json(result); - return next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - return next(); - } + const result = await this.entityService.editEntityAddressById(data); + return res.status(200).json(result); } async deleteEntityLogic(req, res, next) { const { email } = req.decodedToken; - try { - const result = await this.entityService.deleteEntityLogically(email); - res.status(200).json(result); - return next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - return next(); - } + const result = await this.entityService.deleteEntityLogically(email); + return res.status(200).json(result); } async getEntityById(req, res, next) { @@ -92,15 +64,8 @@ class EntityController { email: req.decodedToken.email, }; - try { - const result = await this.entityService.getEntity(data); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(404).json({ error: err.message }); - next(); - } + const result = await this.entityService.getEntity(data); + return res.status(200).json(result); } async updateEntityLocationById(req, res, next) { @@ -110,15 +75,8 @@ class EntityController { longitude: req.body.longitude, }; - try { - const result = await this.entityService.updateEntityLocationById(data); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.entityService.updateEntityLocationById(data); + return res.status(200).json(result); } async checkEntityExistence(req, res, next) { @@ -128,15 +86,8 @@ class EntityController { entityIdentifier = req.decodedToken.email; } - try { - const result = await this.entityService.checkEntityExistence(entityIdentifier); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(404).json({ error: err.message }); - next(); - } + const result = await this.entityService.checkEntityExistence(entityIdentifier); + return res.status(200).json(result); } } diff --git a/src/controllers/HelpController.js b/src/controllers/HelpController.js index cf3bad06..07f2c602 100644 --- a/src/controllers/HelpController.js +++ b/src/controllers/HelpController.js @@ -8,60 +8,37 @@ class HelpController { this.UserService = new UserService(); } - async createHelp(req, res, next) { + async createHelp(req, res) { const data = { ...req.body, }; - try { - await this.HelpService.createHelp(data); - res.status(201).send(); - next(); - } catch (err) { - console.log(err); - saveError(err); - res.status(400).send({ error: err.message }); - next(); - } + await this.HelpService.createHelp(data); + return res.status(201).send(); } - async getHelpWithAggregationById(req, res, next) { + async getHelpWithAggregationById(req, res) { const { id } = req.params; - try { - const result = await this.HelpService.getHelpWithAggregationById(id); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.HelpService.getHelpWithAggregationById(id); + return res.status(200).json(result); } - async getHelpList(req, res, next) { + async getHelpList(req, res) { const { id } = req.query; const coords = req.query.coords.split(',').map((coord) => Number(coord)); const categoryArray = req.query.categoryId ? req.query.categoryId.split(',') : null; /* A requisição do Query é feita com o formato "34312ID12312,12312ID13213", sendo que não é aceito o formato "34312ID12312, 12312ID13213" com espaço */ - try { - const result = await this.HelpService.getHelpList( - coords, - id, - categoryArray, - ); - res.status(200); - res.json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.HelpService.getHelpList( + coords, + id, + categoryArray, + ); + return res.status(200).json(result); } - async getHelpListByStatus(req, res, next) { + async getHelpListByStatus(req, res) { const { userId } = req.params; /* A lista de status deve vir numa query separada por vírgulas @@ -73,111 +50,50 @@ class HelpController { // Caso queira procurar por um helperId é necessário uma query const helper = req.query.helper === 'true'; - try { - const result = await this.HelpService.getHelpListByStatus({ userId, statusList, helper }); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.HelpService.getHelpListByStatus({ userId, statusList, helper }); + return res.status(200).json(result); } - async deleteHelpLogic(req, res, next) { + async deleteHelpLogic(req, res) { const { id } = req.params; - - try { - await this.HelpService.deleteHelpLogically(id); - res.status(204).send(); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + await this.HelpService.deleteHelpLogically(id); + return res.status(204).send(); } - async helperConfirmation(req, res, next) { + async helperConfirmation(req, res) { const data = { ...req.params }; - - try { - await this.HelpService.helperConfirmation(data); - res.status(204).send(); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + await this.HelpService.helperConfirmation(data); + return res.status(204).send(); } - async ownerConfirmation(req, res, next) { + async ownerConfirmation(req, res) { const data = { ...req.params }; - - try { - await this.HelpService.ownerConfirmation(data); - res.status(204).send(); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + await this.HelpService.ownerConfirmation(data); + return res.status(204).send(); } - async chooseHelper(req, res, next) { + async chooseHelper(req, res) { const data = { ...req.params }; - - try { - await this.HelpService.chooseHelper(data); - res.status(204).json(); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - } + await this.HelpService.chooseHelper(data); + return res.status(204).json(); } - async addPossibleHelpers(req, res, next) { + async addPossibleHelpers(req, res) { const id = req.params.idHelp; const { idHelper } = req.params; - - try { - await this.HelpService.addPossibleHelpers(id, idHelper); - res.status(204).send(); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + await this.HelpService.addPossibleHelpers(id, idHelper); + return res.status(204).send(); } - async getToExpireList(req, res, next) { - try { - const result = await this.HelpService.getListToDelete(); - res.status(200); - res.json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + async getToExpireList(req, res) { + const result = await this.HelpService.getListToDelete(); + return res.status(200).json(result); } - async getHelpInfoById(req, res, next) { - try { - const { helpId } = req.params; - const result = await this.HelpService.getHelpInfoById(helpId); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + async getHelpInfoById(req, res) { + const { helpId } = req.params; + const result = await this.HelpService.getHelpInfoById(helpId); + return res.status(200).json(result); } } diff --git a/src/controllers/HelpOfferController.js b/src/controllers/HelpOfferController.js index e14150ee..0f7d9569 100644 --- a/src/controllers/HelpOfferController.js +++ b/src/controllers/HelpOfferController.js @@ -7,61 +7,37 @@ class OfferedHelpController { } async createHelpOffer(req, res) { - try { const newHelpOffer = await this.HelpOfferService.createNewHelpOffer( req.body ); return res.json(newHelpOffer); - } catch (error) { - return res.status(400).json({ error: error.message }); - } } - async getHelpWithAggregationById(req, res, next) { + async getHelpWithAggregationById(req, res) { const { id } = req.params; - - try { - const result = await this.HelpOfferService.getHelpOfferWithAggregationById(id); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).send({ error: err.message }); - next(); - } + const result = await this.HelpOfferService.getHelpOfferWithAggregationById(id); + return res.status(200).json(result); } async listHelpsOffers(req, res) { const userId = req.query.userId; const getOtherUsers = req.query.getOtherUsers == 'true' ? true : false; - try { - const helpOffers = await this.HelpOfferService.listHelpsOffers(userId, null,getOtherUsers); - return res.json(helpOffers); - } catch (error) { - return res.status(400).json({error:error.message}); - } + const helpOffers = await this.HelpOfferService.listHelpsOffers(userId, null,getOtherUsers); + return res.json(helpOffers); } async listHelpOffersByHelpedUserId(req, res) { const { helpedUserId } = req.params; - try { - const helpOffers = await this.HelpOfferService.listHelpOffersByHelpedUserId( - helpedUserId - ); - return res.json(helpOffers); - } catch (error) { - return res.status(400).json(error); - } + const helpOffers = await this.HelpOfferService.listHelpOffersByHelpedUserId( + helpedUserId + ); + return res.json(helpOffers); } async addPossibleHelpedUsers(req, res) { const { helpedId, helpOfferId } = req.params; - try { - await this.HelpOfferService.addPossibleHelpedUsers(helpedId, helpOfferId); - return res.status(204).json(); - } catch (error) { - return res.status(400).json({error:error.message}); - } + await this.HelpOfferService.addPossibleHelpedUsers(helpedId, helpOfferId); + return res.status(204).json(); } async chooseHelpedUser(req, res) {} @@ -70,13 +46,8 @@ class OfferedHelpController { const { helpOfferId } = req.params; const { email } = req.decodedToken; - try { - await this.HelpOfferService.finishHelpOfferByOwner(helpOfferId, email); - return res.status(204).json(); - } catch (error) { - saveError(error); - return res.status(400).send({ error: error.message }); - } + await this.HelpOfferService.finishHelpOfferByOwner(helpOfferId, email); + return res.status(204).json(); } } diff --git a/src/controllers/NotificationController.js b/src/controllers/NotificationController.js index cd7bb479..f56616cc 100644 --- a/src/controllers/NotificationController.js +++ b/src/controllers/NotificationController.js @@ -9,27 +9,14 @@ class NotificationController { async getUserNotificationsById(req, res, next) { const { id } = req.params; - try { - const result = await this.notificationService.getUserNotificationsById(id); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.notificationService.getUserNotificationsById(id); + return res.status(200).json(result); } async sendNotifications(req, res, next) { const { title, body } = req.body; - try { - const result = await this.notificationService.createAndSendNotifications(title, body); - res.status(200).json(result); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.notificationService.createAndSendNotifications(title, body); + return res.status(200).json(result); } } diff --git a/src/controllers/UserController.js b/src/controllers/UserController.js index eeb40ad8..1e8f4e6d 100644 --- a/src/controllers/UserController.js +++ b/src/controllers/UserController.js @@ -21,15 +21,8 @@ class UserController { hasUser: req.query.hasUser === "true", }; - try { - const result = await this.userService.createUser(data); - res.status(201).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.userService.createUser(data); + return res.status(201).json(result); } async editUserById(req, res, next) { @@ -41,15 +34,8 @@ class UserController { notificationToken: req.body.notificationToken, deviceId: req.body.deviceId, }; - try { - const result = await this.userService.editUserById(data); - res.status(200).json(result); - return next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - return next(); - } + const result = await this.userService.editUserById(data); + return res.status(200).json(result); } async editUserAddressById(req, res, next) { @@ -62,101 +48,59 @@ class UserController { complement: req.body.complement, }; - try { - const result = await this.userService.editUserAddressById(data); - res.status(200).json(result); - return next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - return next(); - } + const result = await this.userService.editUserAddressById(data); + return res.status(200).json(result); } - async deleteUserLogic(req, res, next) { + async deleteUserLogic(req, res) { const { email } = req.decodedToken; - try { - const result = await this.userService.deleteUserLogically(email); - res.status(200).json(result); - return next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - return next(); - } + const result = await this.userService.deleteUserLogically(email); + return res.status(200).json(result); } - async getUserById(req, res, next) { + async getUserById(req, res) { const data = { id: req.params.id, email: req.decodedToken.email, }; - try { - const result = await this.userService.getUser(data); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(404).json({ error: err.message }); - next(); - } + const result = await this.userService.getUser(data); + return res.status(200).json(result); } - async getAnyUserById(req, res, next) { + async getAnyUserById(req, res) { const data = { id: req.params.id, }; - try { - const result = await this.userService.getAnyUser(data); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(404).json({ error: err.message }); - next(); - } + + const result = await this.userService.getAnyUser(data); + return res.status(200).json(result); } - async updateUserLocationById(req, res, next) { + async updateUserLocationById(req, res) { const data = { email: req.decodedToken.email, latitude: req.body.latitude, longitude: req.body.longitude, }; - try { - const result = await this.userService.updateUserLocationById(data); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(400).json({ error: err.message }); - next(); - } + const result = await this.userService.updateUserLocationById(data); + return res.status(200).json(result); } - async checkUserExistence(req, res, next) { + async checkUserExistence(req, res) { let { userIdentifier } = req.params; if (!userIdentifier) { userIdentifier = req.decodedToken.email; } - try { - const result = await this.userService.checkUserExistence(userIdentifier); - res.status(200).json(result); - next(); - } catch (err) { - saveError(err); - res.status(404).json({ error: err.message }); - next(); - } + const result = await this.userService.checkUserExistence(userIdentifier); + return res.status(200).json(result); } - async getUserGroupRiskList(req, res, next) { - res.status(200).json(riskGroups); - next(); + async getUserGroupRiskList(req, res) { + return res.status(200).json(riskGroups); } } diff --git a/src/repository/BaseRepository.js b/src/repository/BaseRepository.js index 81dd81cf..1d432413 100644 --- a/src/repository/BaseRepository.js +++ b/src/repository/BaseRepository.js @@ -1,4 +1,5 @@ const mongoose = require('mongoose'); +const { BadRequestError } = require('../utils/errorHandler'); class BaseRepository { constructor(modelClass) { @@ -53,7 +54,7 @@ class BaseRepository { try { finalIdFormat = mongoose.Types.ObjectId(id); } catch (err) { - throw new Error('Tamanho ou formato de id inválido'); + throw new BadRequestError('Tamanho ou formato de id inválido'); } } diff --git a/src/services/CampaignService.js b/src/services/CampaignService.js index bd8e7f1a..9e3b4935 100644 --- a/src/services/CampaignService.js +++ b/src/services/CampaignService.js @@ -1,6 +1,7 @@ const CampaignRepository = require('../repository/CampaignRepository'); const CategoryService = require('./CategoryService'); const helpStatusEnum = require('../utils/enums/helpStatusEnum'); +const { BadRequestError, NotFoundError } = require('../utils/errorHandler'); class CampaignService { constructor() { @@ -25,7 +26,7 @@ class CampaignService { ); if (checkHelpStatusExistence.length > 0) { - throw new Error('Um dos status informados é ínvalido'); + throw new BadRequestError('Um dos status informados é ínvalido'); } const helpList = await this.CampaignRepository.getCampaignListByStatus( @@ -44,7 +45,7 @@ class CampaignService { categoryArray, ); if (!CampaignList) { - throw new Error( + throw new NotFoundError( 'Nenhuma campanha foi encontrada no seu raio de distância', ); } @@ -56,7 +57,7 @@ class CampaignService { const Campaign = await this.CampaignRepository.getById(id); if (!Campaign) { - throw new Error('Campanha não encontrada'); + throw new NotFoundError('Campanha não encontrada'); } return Campaign; diff --git a/src/services/CategoryService.js b/src/services/CategoryService.js index d0251697..c42ce36b 100644 --- a/src/services/CategoryService.js +++ b/src/services/CategoryService.js @@ -1,4 +1,5 @@ const CategoryRepository = require('../repository/CategoryRepository'); +const { NotFoundError } = require('../utils/errorHandler'); class CategoryService { constructor() { @@ -10,7 +11,7 @@ class CategoryService { const Category = await this.CategoryRepository.getById(id); if (!Category) { - throw new Error('Categoria não encontrada'); + throw new NotFoundError('Categoria não encontrada'); } return Category; @@ -19,7 +20,7 @@ class CategoryService { async getCategoryList(id) { const Categorylist = await this.CategoryRepository.list(id); if (!Categorylist) { - throw new Error('Categoria não encontrada'); + throw new NotFoundError('Categoria não encontrada'); } return Categorylist; diff --git a/src/services/EntityService.js b/src/services/EntityService.js index 0e4161f3..14b96f08 100644 --- a/src/services/EntityService.js +++ b/src/services/EntityService.js @@ -2,6 +2,7 @@ const EntityRepository = require("../repository/EntityRepository"); const UserRepository = require("../repository/UserRepository"); const firebase = require("../config/authFirebase"); const { ObjectID } = require("mongodb"); +const { NotFoundError, BadRequestError } = require("../utils/errorHandler"); class EntityService { constructor() { @@ -15,11 +16,11 @@ class EntityService { ); if (isUserRegistered) { - throw new Error("Email já sendo utilizado"); + throw new BadRequestError("Email já sendo utilizado"); } if (data.password.length < 8) { - throw new Error("Senha inválida"); + throw new BadRequestError("Senha inválida"); } if (data.cnpj.length >= 14) { @@ -55,7 +56,7 @@ class EntityService { async getEntity({ id = undefined, email = undefined }) { if (!id && !email) { - throw new Error("Nenhum identificador encontrado"); + throw new BadRequestError("Nenhum identificador encontrado"); } let entity; @@ -65,7 +66,7 @@ class EntityService { entity = await this.entityRepository.getEntityByEmail(email); } if (!entity) { - throw new Error("Usuário não encontrado"); + throw new NotFoundError("Usuário não encontrado"); } return entity; } @@ -79,6 +80,7 @@ class EntityService { deviceId, }) { const entity = await this.getEntity({ email }); + if(!entity) throw new NotFoundError("Usuário não encontrado"); entity.photo = photo || entity.photo; entity.name = name || entity.name; diff --git a/src/services/HelpOfferService.js b/src/services/HelpOfferService.js index b71e3fd0..1ceee4bd 100644 --- a/src/services/HelpOfferService.js +++ b/src/services/HelpOfferService.js @@ -5,6 +5,7 @@ const NotificationService = require("./NotificationService"); const NotificationMixin = require("../utils/NotificationMixin"); const { notificationTypesEnum } = require("../models/Notification"); const saveError = require('../utils/ErrorHistory'); +const { NotFoundError, BadRequestError, UnauthorizedError } = require("../utils/errorHandler"); class OfferedHelpService { constructor() { @@ -26,7 +27,7 @@ class OfferedHelpService { const help = await this.OfferedHelpRepository.getByIdWithAggregation(id); if (!help) { - throw new Error('Oferta não encontrada'); + throw new NotFoundError('Oferta não encontrada'); } return help; @@ -66,10 +67,10 @@ class OfferedHelpService { } if(helpOffer.ownerId == helpedId){ - throw new Error("Usuário não pode ser ajudante da própria oferta"); + throw new BadRequestError("Usuário não pode ser ajudante da própria oferta"); } else if (userPosition > -1) { - throw new Error("Usuário já é um possível ajudado"); + throw new BadRequestError("Usuário já é um possível ajudado"); } await this.useService(possibleHelpedUser,"push",[helpedId]); @@ -117,7 +118,7 @@ class OfferedHelpService { ); if (ownerEmail !== email) { - throw new Error('Usuário não autorizado'); + throw new UnauthorizedError('Usuário não autorizado'); } this.OfferedHelpRepository.finishHelpOfferByOwner(helpOfferId); diff --git a/src/services/HelpService.js b/src/services/HelpService.js index cb9cd153..c7fa53f3 100644 --- a/src/services/HelpService.js +++ b/src/services/HelpService.js @@ -8,6 +8,7 @@ const { findConnections, sendMessage } = require("../../websocket"); const NotificationMixin = require("../utils/NotificationMixin"); const helpStatusEnum = require("../utils/enums/helpStatusEnum"); const saveError = require("../utils/ErrorHistory"); +const { BadRequestError, NotFoundError, UnauthorizedError } = require("../utils/errorHandler"); class HelpService { constructor() { @@ -22,7 +23,7 @@ class HelpService { async createHelp(data) { const countHelp = await this.HelpRepository.countDocuments(data.ownerId); if (countHelp >= 5) { - throw new Error("Limite máximo de pedidos atingido"); + throw new BadRequestError("Limite máximo de pedidos atingido"); } await this.CategoryService.getCategoryByid(data.categoryId); @@ -40,7 +41,7 @@ class HelpService { const Help = await this.HelpRepository.getById(id); if (!Help) { - throw new Error("Ajuda não encontrada"); + throw new NotFoundError("Ajuda não encontrada"); } return Help; @@ -51,7 +52,7 @@ class HelpService { const Help = await this.HelpRepository.getByIdWithAggregation(id); if (!Help) { - throw new Error('Ajuda não encontrada'); + throw new NotFoundError('Ajuda não encontrada'); } return Help; @@ -64,7 +65,7 @@ class HelpService { categoryArray ); if (!Helplist) { - throw new Error( + throw new NotFoundError( "Pedidos de ajuda não encontrados no seu raio de distância" ); } @@ -90,7 +91,7 @@ class HelpService { ); if (checkHelpStatusExistence.length > 0) { - throw new Error("Um dos status informados é ínvalido"); + throw new BadRequestError("Um dos status informados é ínvalido"); } const helpList = await this.HelpRepository.getHelpListByStatus( @@ -116,7 +117,7 @@ class HelpService { const owner = await this.UserService.getUser({ id: ownerId }); if (help.helperId) { - throw new Error("Ajuda já possui ajudante"); + throw new BadRequestError("Ajuda já possui ajudante"); } const sendSocketMessageTo = findConnections( @@ -131,7 +132,7 @@ class HelpService { const userPosition = help.possibleHelpers.indexOf(data.idHelper); const entityPosition = help.possibleEntities.indexOf(data.idHelper); if (userPosition < 0 && entityPosition < 0) { - throw new Error('Ajudante não encontrado'); + throw new NotFoundError('Ajudante não encontrado'); } else { help.helperId = data.idHelper; help.status = "on_going"; @@ -171,7 +172,7 @@ class HelpService { helper = await this.EntityService.getEntity({ id: help.helperId }); } if (help.helperId != data.helperId) { - throw new Error("Usuário não é o ajudante dessa ajuda"); + throw new UnauthorizedError("Usuário não é o ajudante dessa ajuda"); } else if (help.status === "owner_finished") { const ownerTitle = "Pedido de ajuda finalizado!"; const ownerBody = `Seu pedido ${help.title} foi finalizado`; @@ -212,15 +213,14 @@ class HelpService { helperNotificationHistory ); } catch (err) { - console.log("Não foi possível enviar a notificação!"); saveError(err); } help.status = "finished"; } else if (help.status === "helper_finished") { - throw new Error("Usuário já confirmou a finalização da ajuda"); + throw new BadRequestError("Usuário já confirmou a finalização da ajuda"); } else if (help.status === "finished") { - throw new Error("Ajuda já foi finalizada"); + throw new BadRequestError("Ajuda já foi finalizada"); } else { help.status = "helper_finished"; } @@ -239,11 +239,10 @@ class HelpService { } if (help.ownerId != data.ownerId) { - throw new Error("Usuário não é o dono da ajuda"); + throw new UnauthorizedError("Usuário não é o dono da ajuda"); } else if (help.status === "helper_finished") { const ownerTitle = "Pedido de ajuda finalizado!"; const ownerBody = `Seu pedido ${help.title} foi finalizado`; - const ownerNotificationHistory = { userId: help.ownerId, helpId: help._id, @@ -251,7 +250,6 @@ class HelpService { body: ownerBody, notificationType: notificationTypesEnum.ajudaFinalizada, }; - const helperTitle = "Oferta de ajuda finalizada!"; const helperBody = `Sua oferta da ajuda ${help.title} foi finalizada`; const helperNotificationHistory = { @@ -261,7 +259,6 @@ class HelpService { body: helperBody, notificationType: notificationTypesEnum.ajudaFinalizada, }; - try { await this.NotificationMixin.sendNotification( owner.deviceId, @@ -280,19 +277,19 @@ class HelpService { helperNotificationHistory ); } catch (err) { - console.log("Não foi possível enviar a notificação!"); saveError(err); } - help.status = "finished"; - } else if (help.status === "owner_finished") { - throw new Error("Usuário já confirmou a finalização da ajuda"); - } else if (help.status === "finished") { - throw new Error("Essa ajuda já foi finalizada"); } else { - help.status = "owner_finished"; + switch (help.status) { + case "owner_finished": + throw new BadRequestError("Usuário já confirmou a finalização da ajuda"); + case "finished": + throw new BadRequestError("Essa ajuda já foi finalizada"); + default: + help.status = "owner_finished"; + } } - await this.HelpRepository.update(help); } @@ -300,10 +297,10 @@ class HelpService { const help = await this.getHelpByid(id); const owner = await this.UserService.getUser({ id: help.ownerId }); if (idHelper == help.ownerId) { - throw new Error("Você não pode ser ajudante de sua própria ajuda"); + throw new BadRequestError("Você não pode ser ajudante de sua própria ajuda"); } if (help.helperId) { - throw new Error("Ajuda já possui ajudante"); + throw new BadRequestError("Ajuda já possui ajudante"); } let helper; let isUser = false; @@ -315,27 +312,20 @@ class HelpService { } if (isUser) { const userPosition = help.possibleHelpers.indexOf(idHelper); - if (userPosition > -1) { - throw new Error("Usuário já é um possível ajudante"); + throw new BadRequestError("Usuário já é um possível ajudante"); } - help.possibleHelpers.push(idHelper); } else { const userPosition = help.possibleEntities.indexOf(idHelper); - if (userPosition > -1) { - throw new Error("Usuário já é um possível ajudante"); + throw new BadRequestError("Usuário já é um possível ajudante"); } - help.possibleEntities.push(idHelper); } - await this.HelpRepository.update(help); - const title = `${helper.name} quer te ajudar!`; const body = `Seu pedido ${help.title} recebeu uma oferta de ajuda`; - const notificationHistory = { userId: help.ownerId, helpId: help._id, @@ -343,7 +333,6 @@ class HelpService { body, notificationType: notificationTypesEnum.ajudaRecebida, }; - try { await this.NotificationMixin.sendNotification( owner.deviceId, @@ -360,7 +349,7 @@ class HelpService { async getListToDelete() { const Helplist = await this.HelpRepository.listToExpire(); if (!Helplist) { - throw new Error("Pedidos de ajuda não encontrados"); + throw new NotFoundError("Pedidos de ajuda não encontrados"); } return Helplist; @@ -369,7 +358,7 @@ class HelpService { async getHelpInfoById(helpId) { const helpInfo = await this.HelpRepository.getHelpInfoById(helpId); if (!helpInfo) { - throw new Error('Pedido de ajuda não encontrado'); + throw new NotFoundError('Pedido de ajuda não encontrado'); } return helpInfo; } diff --git a/src/services/UserService.js b/src/services/UserService.js index caff3905..51a965c7 100644 --- a/src/services/UserService.js +++ b/src/services/UserService.js @@ -2,6 +2,7 @@ const UserRepository = require("../repository/UserRepository"); const EntityRepository = require("../repository/EntityRepository"); const firebase = require("../config/authFirebase"); const { ObjectID } = require("mongodb"); +const { ConflictError, BadRequestError, NotFoundError } = require("../utils/errorHandler"); class UserService { constructor() { @@ -15,11 +16,11 @@ class UserService { ); if (isEntityRegistered) { - throw new Error("Email já sendo utilizado"); + throw new ConflictError("Email já sendo utilizado"); } if (data.password.length < 8) { - throw new Error("Senha inválida"); + throw new BadRequestError("Senha inválida"); } if (data.cpf.length >= 11) { @@ -63,7 +64,7 @@ class UserService { async getUser({ id = undefined, email = undefined }) { if (!id && !email) { - throw new Error("Nenhum identificador encontrado"); + throw new NotFoundError("Nenhum identificador encontrado"); } let user; @@ -73,14 +74,14 @@ class UserService { user = await this.userRepository.getUserByEmail(email); } if (!user) { - throw new Error("Usuário não encontrado"); + throw new NotFoundError("Usuário não encontrado"); } return user; } async getAnyUser({ id = undefined, email = undefined }) { if (!id && !email) { - throw new Error("Nenhum identificador encontrado"); + throw new NotFoundError("Nenhum identificador encontrado"); } let user; @@ -89,7 +90,7 @@ class UserService { if (!user) user = await this.entityRepository.getById(id); } if (!user) { - throw new Error("Usuário não encontrado"); + throw new NotFoundError("Usuário não encontrado"); } return user; } diff --git a/src/utils/errorHandler.js b/src/utils/errorHandler.js new file mode 100644 index 00000000..f3f4ed8f --- /dev/null +++ b/src/utils/errorHandler.js @@ -0,0 +1,65 @@ +import saveError from "./ErrorHistory"; + +export const errorHandler = (err, req, res, next) => { + if(err instanceof GeneralError) { + return res.status(err.getCode()).json({ + status: 'error', + message: err.message + }); + } + + saveError(err); + return res.status(500).json({ + status: 'error', + message: 'Internal server error' + }) +} + +export class GeneralError extends Error { + constructor(msg) { + super(msg); + } + + getCode() { + if(this instanceof BadRequestError) return 400; + else if(this instanceof UnauthorizedError) return 404; + else if(this instanceof ForbiddenError) return 404; + else if(this instanceof NotFoundError) return 404; + else if(this instanceof ConflictError) return 409; + } +} + +export class BadRequestError extends GeneralError { + constructor(msg) { + super(msg); + this.name = `BadRequestError:${msg}`; + } +} + +export class UnauthorizedError extends GeneralError { + constructor(msg) { + super(msg); + this.name = `UnauthorizedError:${msg}`; + } +} + +export class ForbiddenError extends GeneralError { + constructor(msg) { + super(msg); + this.name = `ForbiddenError:${msg}`; + } +} + +export class NotFoundError extends GeneralError { + constructor(msg) { + super(msg); + this.name = `NotFoundError:${msg}`; + } +} + +export class ConflictError extends GeneralError { + constructor(msg) { + super(msg); + this.name = `ConflictError:${msg}`; + } +} \ No newline at end of file diff --git a/src/validation/middlewares/authFirebase.js b/src/validation/middlewares/authFirebase.js index 922379ca..948319cc 100644 --- a/src/validation/middlewares/authFirebase.js +++ b/src/validation/middlewares/authFirebase.js @@ -1,6 +1,7 @@ const admin = require('../../config/authFirebase'); const saveError = require('../../utils/ErrorHistory'); const isEntity = require('../../utils/IsEntity'); +const { ForbiddenError, UnauthorizedError } = require('../../utils/errorHandler'); const isAuthenticated = async (req, res, next) => { if (req.headers.authorization @@ -17,11 +18,10 @@ const isAuthenticated = async (req, res, next) => { return next(); } catch (err) { - saveError(err); - return res.status(401).json({ error: 'Usuário não autorizado' }); + throw new UnauthorizedError('Usuário não está autorizado'); } } - const err = new Error('Usuário não está autenticado'); + const err = new ForbiddenError('Usuário não está autenticado'); saveError(err); return res.status(403).json({ error: err.message }); }; From b01c7c5e5eee49c2fbab3164234727ea5d60df35 Mon Sep 17 00:00:00 2001 From: Brian Pina Date: Mon, 13 Sep 2021 20:33:59 -0300 Subject: [PATCH 2/2] fix: change getCode method and id from finishCampaign --- index.js | 2 +- src/controllers/CampaignController.js | 1 + src/utils/errorHandler.js | 39 +++++++++++++++++---------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/index.js b/index.js index f8f2effa..ad4915e8 100644 --- a/index.js +++ b/index.js @@ -22,12 +22,12 @@ const { errorHandler } = require('./src/utils/errorHandler'); app.use(cors()); app.use(bodyParser.json()); +app.use(errorHandler); databaseConnect(); dailySchedule(); setRoutes(app); -app.use(errorHandler); app.use(Sentry.Handlers.errorHandler()); server.listen(8000); diff --git a/src/controllers/CampaignController.js b/src/controllers/CampaignController.js index 44aee146..1db5c2a6 100644 --- a/src/controllers/CampaignController.js +++ b/src/controllers/CampaignController.js @@ -80,6 +80,7 @@ class CampaignController { } async finishCampaign(req, res) { + const { id } = req.params; if(!id) throw new BadRequestError('No id provided'); const result = await this.CampaignService.finishCampaign(id); return res.status(200).json(result); diff --git a/src/utils/errorHandler.js b/src/utils/errorHandler.js index f3f4ed8f..b9fa916f 100644 --- a/src/utils/errorHandler.js +++ b/src/utils/errorHandler.js @@ -1,6 +1,6 @@ -import saveError from "./ErrorHistory"; +const saveError = require('./ErrorHistory'); -export const errorHandler = (err, req, res, next) => { +const errorHandler = (err, _req, res, _next) => { if(err instanceof GeneralError) { return res.status(err.getCode()).json({ status: 'error', @@ -15,51 +15,62 @@ export const errorHandler = (err, req, res, next) => { }) } -export class GeneralError extends Error { +class GeneralError extends Error { constructor(msg) { super(msg); } getCode() { - if(this instanceof BadRequestError) return 400; - else if(this instanceof UnauthorizedError) return 404; - else if(this instanceof ForbiddenError) return 404; - else if(this instanceof NotFoundError) return 404; - else if(this instanceof ConflictError) return 409; + return this.code; } } -export class BadRequestError extends GeneralError { +class BadRequestError extends GeneralError { constructor(msg) { super(msg); + this.code = 400; this.name = `BadRequestError:${msg}`; } } -export class UnauthorizedError extends GeneralError { +class UnauthorizedError extends GeneralError { constructor(msg) { super(msg); + this.code = 401; this.name = `UnauthorizedError:${msg}`; } } -export class ForbiddenError extends GeneralError { +class ForbiddenError extends GeneralError { constructor(msg) { super(msg); + this.code = 403; this.name = `ForbiddenError:${msg}`; } } -export class NotFoundError extends GeneralError { +class NotFoundError extends GeneralError { constructor(msg) { super(msg); + this.code = 404; this.name = `NotFoundError:${msg}`; } } -export class ConflictError extends GeneralError { +class ConflictError extends GeneralError { constructor(msg) { super(msg); + this.code = 409; this.name = `ConflictError:${msg}`; } -} \ No newline at end of file +} + +module.exports = { + errorHandler, + BadRequestError, + ConflictError, + ForbiddenError, + GeneralError, + NotFoundError, + UnauthorizedError +}; \ No newline at end of file