'use strict'; const { MulterError } = require("multer"), { ValidationError } = require("joi"), { Errors, LIMIT_FILE_SIZE_ERR } = require('../helpers/constants'), { AppError } = require("../helpers/app_error"), env = require('../helpers/env'), utils = require('../helpers/utils'), debug = require('debug')('agm:errHandler'); function createAppErrObj(tag = Errors.UNKNOWN_APP_ERROR) { return { error: { '.tag': tag } }; } function createAppValidationErrObj(valError) { let errObj = createAppErrObj(Errors.INVALID_PARAM); if (!utils.isEmptyObj(valError) && valError.message) { errObj.error.message = valError.message; } return errObj; } /** * Handle Application error for a given request with the provided error object * @param {*} req The Request object of the request * @param {*} res The Response object of the request * @param {*} err The error object (runtime error object or App* error classes) * Notes: return HTTP statusCode for the custom App errors with 409 as default. * For Stripe errors the code will always be 402. The client should base on the .code value for detail error. * @returns */ function ErrorHandler(err, req, res, next) { const statusCode = err && err.statusCode || 409; // Application error default http status code try { if (err.type && err.type.startsWith('Stripe')) { /* For Stripe errors the code will always be 402. The client should base on the .code value for detail error. TODO: In Production mode => consider to filter Stripe errors thus sending back with less detail ?? */ return res.status(402).send(err); } if (err instanceof ValidationError) { return res.status(statusCode).send(createAppValidationErrObj(err)); } if (err instanceof AppError) { return res.status(err.statusCode).send(createAppErrObj(err.message)); } // Duplication index error throwing from Mongoose model. For example: username, unitId if (typeof err === "object" && err.code === 11000) { return res.status(statusCode).send(createAppErrObj(Errors.DUPLICATED_VALUE)); } if (err instanceof MulterError) { return res.status(statusCode).send(createAppErrObj(err.code == LIMIT_FILE_SIZE_ERR ? Errors.FILE_TOO_LARGE : Errors.INVALID_PARAM)); } res.status(500).send(createAppErrObj(Errors.UNKNOWN_ERROR)); } catch (error) { res.status(500).send(createAppErrObj(Errors.UNKNOWN_APP_ERROR)); } finally { env.LOG_ALL_ERRORS && (debug(err)); } } module.exports = { ErrorHandler }