【发布时间】:2020-12-09 04:11:58
【问题描述】:
问题:我在我的代码中引入了错误处理,它应该在出现问题时呈现错误页面和错误消息。在这个特定的例子中,当用户试图在没有登录的情况下访问保护路由时,应该会显示一个错误页面。相反,Heroku 只是等待 30 秒然后崩溃。奇怪的是,在 LocalHost 上一切正常。
虽然我不确定,但我相信错误来自下面代码中的某个地方(调用 const sendErrorDev 函数时)。在我介绍这个之前,一切正常。但是,我不确定是什么导致 Heroku 与 LocalHost 的结果不同。
const AppError = require('../utils/appError');
const JsonWebTokenError = () =>
new AppError('Invalid token. Please login again!', 401);
const handleJWTExpiredError = () =>
new AppError('Your token has EXPIRED! What?!', 401);
const handleCastErrorDB = err => {
const message = `Invalid ${err.path}: ${err.value}.`;
return new AppError(message, 400);
};
const handleDuplicateFieldsDB = err => {
const value = err.errmsg.match(/(["'])(?:(?=(\\?))\2.)*?\1/)[0];
console.log(value);
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, 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
return res.status(err.statusCode).render('error', {
title: 'Something went wrong!',
msg: err.message
});
};
const sendErrorProd = (err, req, res) => {
// A) API
console.log('This is working!!!');
if (req.originalUrl.startsWith('/api')) {
// A) Trusted operaitonal error, okay to send the details to the client.
if (err.isOperational) {
return res.status(err.statusCode).json({
status: err.status,
message: err.message
});
}
// Weird coding errors, don't leak the details to the client.
// 1.) Log the error to the
console.error('ERROR!', err);
// 2.) Send generic message to the client
return res.status(500).json({
status: 'error',
message: 'Something went very wrong! JESUS!'
});
}
// B) Rendered Website
if (err.isOperational) {
console.log(err);
return res.status(err.statusCode).render('error', {
title: 'Something went wrong!',
msg: err.message
});
}
// Weird coding errors, don't leak the details to the client.
// 1.) Log the error to the
console.error('ERROR!', err);
// 2.) Send generic message to the client
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.code === 11000) error = handleDuplicateFieldsDB(error);
if (error.name === 'ValidationError')
error = handleValidationErrorDB(error);
if (error.name === 'JsonWebTokenError') error = JsonWebTokenError();
if (error.name === 'TokenExpiredError') error = handleJWTExpiredError();
sendErrorProd(error, req, res);
}
};
【问题讨论】:
标签: javascript node.js heroku error-handling