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

无法将res.status设为404并在错误中间件中处理该状态码

解决Express异步控制器404状态码未传递到错误中间件的问题

问题原因

你的异步控制器中抛出的错误没有被Express正确捕获并传递给错误中间件。async函数中抛出的错误会以Promise Reject的形式存在,Express不会自动处理这种情况,导致错误中间件无法接收到正确的状态码;另外错误中间件中没有明确设置响应状态码,可能导致状态码被覆盖。

解决方案

1. 修正控制器代码,确保错误传递给next

将控制器中的throw new Error改为手动调用next(err),或者用try/catch包裹异步逻辑并传递错误:

方式一:直接调用next传递错误

// Controller
const contact = await Contact.findById(req.params.id);
if (!contact) {
    res.status(404);
    // 调用next传递错误给中间件
    return next(new Error("Contact not Found"));
}

res.status(200).json({ message: `Got contact with id: ${req.params.id}`, contact });

方式二:使用try/catch捕获异步错误

// Controller
try {
    const contact = await Contact.findById(req.params.id);
    if (!contact) {
        res.status(404);
        throw new Error("Contact not Found");
    }
    res.status(200).json({ message: `Got contact with id: ${req.params.id}`, contact });
} catch (err) {
    // 将捕获的错误传递给错误中间件
    next(err);
}

2. 完善错误中间件,明确设置响应状态码

在错误中间件的每个case分支中,先设置响应状态码再返回JSON,确保状态码正确传递:

// Middleware Error Handler
const { constants } = require("../constants");

const errorHandler = (err, req, res, next) => {
    const statusCode = res.statusCode ? res.statusCode : 500;
    console.log(statusCode);
    // 先设置响应状态码
    res.status(statusCode);
    switch(statusCode) {
        case constants.VALIDATION_ERR: 
            res.json({
                title: "Validation Failed",
                message: err.message,
                stackTrace: err.stack,
            });
            break;
        case constants.FORBIDDEN: 
            res.json({
                title: "Forbidden",
                message: err.message,
                stackTrace: err.stack,
            });
            break;
        case constants.NOT_FOUND: 
            res.json({
                title: "Not Found",
                message: err.message,
                stackTrace: err.stack,
            });
            break;
        case constants.UNAUTHORIZE: 
            res.json({
                title: "warning ! Unauthorized",
                message: err.message,
                stackTrace: err.stack,
            });
            break;
        case constants.SERVER_ERR: 
            res.json({
                title: "Server Error",
                message: err.message,
                stackTrace: err.stack,
            });
            break;
        default: 
            console.log("no Error, Everything is Good ");
            res.json({ status: "ok" });
            break;
    }
}

module.exports = errorHandler;

说明

  • Express的错误中间件仅能处理同步代码抛出的错误,以及通过next(err)传递的错误。对于async函数中的错误,必须手动捕获并通过next(err)传递,否则Express无法将其路由到自定义错误中间件。
  • 在错误中间件中明确设置res.status(statusCode)可以避免之前设置的状态码被覆盖,确保响应的状态码与错误类型匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 05:30:13