Created
August 2, 2020 17:31
-
-
Save navsqi/a5c5e992464e1cce51b4b1b5e92fcdc4 to your computer and use it in GitHub Desktop.
sequelize global error handling
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// in models/index.js | |
if (sequelize) { | |
sequelize | |
.authenticate() | |
.then(() => { | |
console.log('Connection has been established successfully.'); | |
}) | |
.catch((err) => { | |
console.error('Unable to connect to the database:', err); | |
}); | |
} | |
// file: globalError.js | |
const AppError = require('./../utils/appError'); | |
// const handleCastErrorDB = (err) => { | |
// const message = `Invalid ${err.path}: ${err.value}.`; | |
// return new AppError(message, 400); | |
// }; | |
const handleDuplicateFieldsDB = (err) => { | |
const value = err.errors[0].message; | |
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 handleJWTError = () => new AppError('Invalid token. Please log in again!', 401); | |
const handleJWTExpiredError = () => | |
new AppError('Your token has expired! Please log in again.', 401); | |
const sendErrorDev = (err, req, res) => { | |
// A) API | |
if (req.originalUrl.startsWith('/api')) { | |
return res.status(err.statusCode).json({ | |
status: err.status, | |
error: err, | |
message: err.message, | |
stack: err.stack, | |
}); | |
} | |
// B) RENDERED WEBSITE | |
console.error('ERROR 💥', err); | |
return res.status(err.statusCode).render('error', { | |
title: 'Something went wrong!', | |
msg: err.message, | |
}); | |
}; | |
const sendErrorProd = (err, req, res) => { | |
// A) API | |
if (req.originalUrl.startsWith('/api')) { | |
// A) Operational, trusted error: send message to client | |
if (err.isOperational) { | |
return res.status(err.statusCode).json({ | |
status: err.status, | |
message: err.message, | |
}); | |
} | |
// B) Programming or other unknown error: don't leak error details | |
// 1) Log error | |
console.error('ERROR 💥', err); | |
// 2) Send generic message | |
return res.status(500).json({ | |
status: 'error', | |
message: 'Something went very wrong!', | |
}); | |
} | |
// B) RENDERED WEBSITE | |
// A) Operational, trusted error: send message to client | |
if (err.isOperational) { | |
return res.status(err.statusCode).render('error', { | |
title: 'Something went wrong!', | |
msg: err.message, | |
}); | |
} | |
// B) Programming or other unknown error: don't leak error details | |
// 1) Log error | |
console.error('ERROR 💥', err); | |
// 2) Send generic message | |
return res.status(err.statusCode).render('error', { | |
title: 'Something went wrong!', | |
msg: 'Please try again later.', | |
}); | |
}; | |
module.exports = (err, req, res, next) => { | |
// console.log(err.stack); | |
err.statusCode = err.statusCode || 500; | |
err.status = err.status || 'error'; | |
if (process.env.NODE_ENV === 'development') { | |
sendErrorDev(err, req, res); | |
} else if (process.env.NODE_ENV === 'production') { | |
let error = { ...err }; | |
error.message = err.message; | |
if (error.name === 'CastError') error = handleCastErrorDB(error); | |
if (error.name === 'SequelizeUniqueConstraintError') error = handleDuplicateFieldsDB(error); | |
if (error.name === 'SequelizeValidationError') error = handleValidationErrorDB(error); | |
if (error.name === 'JsonWebTokenError') error = handleJWTError(); | |
if (error.name === 'TokenExpiredError') error = handleJWTExpiredError(); | |
sendErrorProd(error, req, res); | |
} | |
}; | |
// file: appError.js | |
class AppError extends Error { | |
constructor(message, statusCode) { | |
super(message); | |
this.statusCode = statusCode; | |
this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error'; | |
this.isOperational = true; | |
Error.captureStackTrace(this, this.constructor); | |
} | |
} | |
module.exports = AppError; | |
// file: catchAsync.js | |
module.exports = (fn) => { | |
return (req, res, next) => { | |
fn(req, res, next).catch(next); | |
}; | |
}; | |
// in app.js | |
app.all('*', (req, res, next) => { | |
next(new AppError(`Can't find ${req.originalUrl} on this server!`, 404)); | |
}); | |
app.use(globalErrorHandler); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment