const AppError = require('./AppError') const ErrorLocalization = require('./errorLocalization') const el = new ErrorLocalization() const handleCastErrorDB = (err) => { const message = `Invalid ${err.path} : ${err.value}` return new AppError(message, 400) } const handleDuplicateFieldsDB = (err) => { const value = err.message.match(/(["'])(\\?.)*?\1/)[0] const message = `Duplicate field value: ${value}. Please use another value!` return new AppError(message, 400) } const handleValidationErrorDB = (err) => { const errors = Object.values(err.errors).map((el) => el.message) const message = `Invalid input data. ${errors.join('. ')}` return new AppError(message, 400) } const sendErrorDev = (err, res) => { res.status(err.statusCode).json({ status: err.status, error: err, message: err.message, stack: err.stack, }) } const sendErrorProd = (err, res) => { // Operational, trusted error: send message to client if (err.isOperational) { res.status(err.statusCode).json({ status: err.status, message: err.message, }) // Programming or other unknown error: don't leak error details } else { // 1) Log error console.log('ERROR', err) // 2) send generic message: res.status(500).json({ status: 'error', message: 'Something went wrong', }) } } module.exports = (err, req, res, next) => { console.log(err) err.statusCode = err.statusCode || 500 err.status = err.status || 'error' err.message = el.getErrorText(err.name, err.parameters, 'persian') || err.message if (process.env.NODE_ENV === 'development' || process.env.NODE_ENV === 'test') { sendErrorDev(err, res) } else if (process.env.NODE_ENV === 'production') { let error = { ...err } error.message = err.message if (error.name === 'CastError') error = handleCastErrorDB(error) if (error.code === 11000) error = handleDuplicateFieldsDB(error) if (error.name === 'ValidationError') error = handleValidationErrorDB(error) // send error to production sendErrorProd(error, res) } }