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

ExpressJS如何全局处理500/404/401/403等特定HTTP错误

问题原因

你的错误处理不生效是核心写法不符合Express中间件执行规则导致的:

  • 注册顺序错误:Express按照代码从上到下的顺序匹配执行中间件、路由,你把app.listen写在路由和错误中间件前面,部分场景下会导致请求处理逻辑未加载完成就启动端口监听。
  • 误用废弃API:app.use(app.router)是Express 3的遗留写法,Express 4+版本已内置路由处理逻辑,加这行会打乱中间件执行栈顺序。
  • 未覆盖路由不匹配场景:用户访问不存在的路径时,Express不会主动抛出错误,不会进入4参数格式的错误处理中间件,需要在所有路由末尾加兜底逻辑主动抛404错误。
  • 错误处理末尾多余调用:你已经向客户端返回响应后再调用next(err),会触发Express内置默认错误处理器,覆盖已返回的结果。
  • 注意:所有业务逻辑里的401、403、500错误,都需要通过next(错误对象)的方式传递给全局错误中间件,不要在路由里单独写响应逻辑。
修正后完整代码
import express from 'express';
import 'dotenv/config';

//import atlasConnection from './database/mongo-connection.js';
//import erroHandler from './middlewares/error.middleware.js';
//await atlasConnection();

const port = process.env.PORT;
const app = express();

// 全局基础中间件要写在路由前面,按需开启
// app.use(express.json())
// app.use(posts);
// app.use(users);

app.get('/api', (req, res, next) => {
  res.send('test')
})

// 所有路由注册完成后,加无匹配路由兜底
app.use('*', (req, res, next) => {
  const notFoundErr = new Error('Resource not found');
  notFoundErr.status = 404;
  next(notFoundErr);
})

// 全局错误处理中间件,必须写在所有路由、404兜底逻辑后面
app.use(function(err, req, res, next ) {
  // 开发环境可打印错误日志排查问题,生产环境按需关闭
  console.error(err);

  const statusCode = err.status || 404;
  const baseRes = {
    success: false,
    code: 4001,
    error: "Resource not found"
  };

  switch (statusCode) {
    case 500:
      baseRes.error = "Server Error";
      break;
    case 401:
      baseRes.code = 2001;
      baseRes.error = "Unauthorized";
      break;
    case 403:
      baseRes.code = 2002;
      baseRes.error = "Forbidden";
      break;
    // 404和其余未知错误统一走默认返回逻辑,无需额外写case
  }

  res.status(statusCode).json(baseRes);
  // 已返回响应,不要再调用next(err)
})

// listen必须写在所有中间件、路由注册的最末尾
if (process.env.NODE_ENV !== 'test') {
  app.listen(port, () => console.log(`Server listening on port ${port}`));
}

export default app;
使用说明
  • 业务路由里需要抛出401/403/500错误时,直接构造带status属性的Error对象传给next即可,示例:
// 鉴权失败场景示例
app.get('/api/protected', (req, res, next) => {
  if (!req.headers.authorization) {
    const unauthErr = new Error('Unauthorized');
    unauthErr.status = 401;
    return next(unauthErr);
  }
  // 正常业务逻辑
})
  • 异步路由的错误如果是Express 4版本,需要手动catch后传给next,或者引入express-async-errors包做全局兼容;Express 5版本默认支持异步错误直接传递,无需额外处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 05:18:19