mongoose 在生产环境中,客户端没有得到他们需要得到的响应

nxowjjhe  于 2023-08-06  发布在  Go
关注(0)|答案(1)|浏览(77)

我编写了这个AppError类,它将满足我的全局错误处理中间件对操作和编程错误的响应。

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;

字符串
这里是我的全局错误处理中间件,它具有使其工作的所有必要功能。

const AppError = require('./AppError');

//global error handling middleware all errors go into it
module.exports = (err, req, res, next)=>{
     err.statusCode = err.statusCode || 500;
     err.status = err.status || 'error';

     if(process.env.NODE_ENV === 'development'){
          sendErrorDev(err, res)
     }

     else if(process.env.NODE_ENV === 'production'){
          let error = {...err};
          if(error.name === 'CastError') error = handleCastErrorDB(error);
          sendErrorProd(err, res)
     }
};

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
          });
     }else{
          // Programming or other unknown error: don't send details to client
          //1_console err
          console.log('error: ', err);
          //2_send generic message to client
          res.status(500).json({
               status: 'error',
               message: 'Something went very wrong!'
          });
     };
};

const handleCastErrorDB = err => {
     const message = `Invalid ${err.path}: ${err.value}`;
     return new AppError(message, 400)
};


我的问题是,在生产环境中,当我试图通过GET请求获取数据时,客户端没有得到他们应该得到的错误,我正在用 Postman 测试它。更详细地说,为了测试客户端正在获取什么,我试图获取具有无效ID的数据……

127.0.0.1:3000/api/v1/tours/wwwwwwwwwwwwwwwwwww


这是客户端的错误,因此,他们应该得到handleCastErrorDB中设置的400状态代码的响应,但相反,我看到500状态代码的消息

"status": "error",
    "message": "Something went very wrong!"


这是客户端在错误不可操作时将获得的响应。参见sendErrorProd()函数。
在开发模式下,我得到了我想要的东西,但藏在这里。
我在node.js中处于学习模式,我已经尝试了我所知道的一切。

whlutmcx

whlutmcx1#

首先,在下面的代码中。在mongoose的最新版本中,我认为error.name不直接存在。
问题是,当您使用spread操作符复制err对象时,您并没有复制它的不可枚举属性,例如name。这意味着您的error.name在生产环境中将是undefined,您的错误处理逻辑将无法正常工作

//global error handling middleware all errors go into it
module.exports = (err, req, res, next)=>{
     err.statusCode = err.statusCode || 500;
     err.status = err.status || 'error';

     if(process.env.NODE_ENV === 'development'){
          sendErrorDev(err, res)
     }

     else if(process.env.NODE_ENV === 'production'){
          let error = {...err};
          if(error.name === 'CastError') error = handleCastErrorDB(error);
          sendErrorProd(err, res)
     }
};

字符串
要解决这个问题,需要显式复制name属性,如下所示:
您应该替换此行:

let error = {...err};


用这个:

let error = { ...err, name: err.name };


这样,您的error.name将被保留,您的handleCastErrorDB函数将被正确调用。
第二,我不知道为什么,但是在生产模式下没有响应的原因是你正在使用nodemon脚本运行服务器(我认为就是这样:第一个月
由于某种原因,当您发出请求时,它不会发送响应。
所以,要解决这个问题,只需在config.env文件**中手动编辑NODE_ENV=developmentNODE_ENV=production**即可。

**然后,**从VSCode终端运行npm start而不是npm run start:prod

或者如果您仍然想使用脚本而不是手动编辑config.env**,您只需要做一点更改**就可以正常工作。下面是你应该做的:
1.全局安装跨环境npm包npm install cross-env --global
1.不使用前面的脚本,只添加这个脚本"start:prod": "cross-env NODE_ENV=production nodemon server.js"
1.运行脚本npm run start:prod
我希望这对你有点帮助。

相关问题