agmission/Development/server/middlewares/error_handler.js

70 lines
2.5 KiB
JavaScript

'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 }