【问题标题】:How to throw a 404 error in express.js?如何在 express.js 中抛出 404 错误?
【发布时间】:2021-09-26 05:02:13
【问题描述】:

在 app.js 中,我有

// catch 404 and forward to error handler
app.use(function(req, res, next) {
  var err = new Error('Not Found');
  err.status = 404;
  next(err);
});

所以如果我请求一些不存在的 url,比如http://localhost/notfound,上面的代码就会执行。

http://localhost/posts/:postId这样的现有网址中,我想在访问一些不存在的postId或删除的postId时抛出404错误。

Posts.findOne({_id: req.params.id, deleted: false}).exec()
  .then(function(post) {
    if(!post) {
      // How to throw a 404 error, so code can jump to above 404 catch?
    }

【问题讨论】:

  • 这个Posts.findOne是在页面请求中调用还是在页面请求中调用promise?

标签: javascript node.js express


【解决方案1】:

In Express, a 404 isn't classed as an 'error', so to speak - 这背后的原因是 404 通常不是出现问题的迹象,只是服务器找不到任何东西。最好的办法是在路由处理程序中显式发送 404:

Posts.findOne({_id: req.params.id, deleted: false}).exec()
  .then(function(post) {
    if(!post) {
      res.status(404).send("Not found.");
    }

或者,如果感觉重复代码太多,您可以随时将该代码提取到函数中:

function notFound(res) {
    res.status(404).send("Not found.");
}

Posts.findOne({_id: req.params.id, deleted: false}).exec()
      .then(function(post) {
        if(!post) {
          notFound(res);
        }

我不建议在这种情况下仅使用中间件,因为我觉得它会使代码不那么清晰 - 404 是数据库代码找不到任何东西的直接结果,因此在路由处理程序。

【讨论】:

    【解决方案2】:

    我有相同的app.js结构,我在路由处理程序中通过这种方式解决了这个问题:

    router.get('/something/:postId', function(req, res, next){
        // ...
        if (!post){
            next();
            return;
        }
        res.send('Post exists!');  // display post somehow
    });
    

    next() 函数将调用下一个中间件,即 error404 处理程序,如果它位于 app.js 中的路由之后。

    【讨论】:

    • 返回下一个(); ?
    【解决方案3】:

    你可以用这个和你的路由器的末端。

    app.use('/', my_router);
    ....
    app.use('/', my_router);
    
    app.use(function(req, res, next) {
            res.status(404).render('error/404.html');
        });
    

    【讨论】:

      【解决方案4】:

      【讨论】:

        【解决方案5】:

        尽管 404 页面在 Express 中不被视为错误,如 here 所写,但如果您像这样处理它们,它真的很方便。例如,当您开发需要一致 JSON 输出的 API 时。以下代码应该可以帮助您:

        定义一个辅助函数 abort 来创建可以在您的代码中轻松使用以传递给 next 函数的状态错误:

        // Use the `statuses` package which is also a dependency of Express.
        const status = require('statuses');
        
        const abort = (code) => {
            const err = new Error(status[code]);
            const err.status = code;
            return err;
        };
        

        为 404 页面定义包罗万象的中间件,该中间件应在堆栈底部定义(在添加所有路由之后)。这会将 404 作为错误转发:

        app.use((req, res, next) => {
            next(abort(404));
        });
        

        最后,最终的错误处理程序现在将一致地以 JSON 格式发送所有错误:

        app.use((err, req, res, next) => {
            
            if(!res.headersSent) {
                // You can define production mode here so that the stack trace will not be sent.
                const isProd = false;
                res.status(err.status || 500).json({
                    error: err.toString(),
                    ...(!isProd && {stack: err.stack.split('\n').map(i => i.trim())}),
        
                });
            }
            next(err);
        });
        
        

        【讨论】:

          猜你喜欢
          • 2014-09-08
          • 2012-06-24
          • 2011-03-16
          • 2023-03-26
          • 1970-01-01
          • 2020-03-24
          • 2017-10-17
          • 2017-11-20
          • 2020-08-10
          相关资源
          最近更新 更多