You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生产环境错误处理时isOperational未定义问题求助

问题排查与修复方案

核心问题1:对象展开丢失Error实例的非枚举属性

你在生产环境中用let error = { ...err };复制错误对象,但Error实例的自定义属性(比如你定义的isOperational)属于非枚举属性,对象展开语法只能复制可枚举属性,因此新生成的error对象会丢失isOperational、statusCode这些关键标记。

修复方式:

替换对象展开逻辑,改用Object.assign复制所有属性(包括非枚举属性),同时保留原错误的原型链:

// 替换原有的 { ...err } 代码
let error = Object.assign(Object.create(Object.getPrototypeOf(err)), err);

或者手动补全丢失的核心属性:

let error = { ...err };
// 手动复制非枚举的自定义属性
error.isOperational = err.isOperational;
error.statusCode = err.statusCode;
error.status = err.status;

核心问题2:CastError的名称判断错误

你代码中判断error.name === 'Cast',但MongoDB抛出的类型错误实际名称是**CastError**,这导致数据库类型错误无法被转换为AppError实例,自然也不会有isOperational属性。

修复方式:

修正判断条件:

if (error.name === 'CastError') error = handleCastErrorDB(error);

修复后的核心代码片段

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') {
    // 正确复制Error实例的所有属性
    let error = Object.assign(Object.create(Object.getPrototypeOf(err)), err);

    if (error.name === 'CastError') error = handleCastErrorDB(error);
    sendErrorProd(error, res);
  }

  next();
};

额外验证提示

确保业务代码中抛出可运行错误时,统一使用new AppError()创建实例,比如:

throw new AppError('Invalid credentials', 401);

只有这样抛出的错误才会自带isOperational: true标记。


内容的提问来源于stack exchange,提问作者Nikhil Raj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 17:27:32