具有Express的Node.js - 抛出错误vs next(错误)

Ale*_*lls 12 node.js express

有人可以在node.js Express应用程序中说明适当的时间来抛出错误,如下所示:

throw new Error('my error');
Run Code Online (Sandbox Code Playgroud)

或者通过回调传递此错误,通常标记为'next',如下所示:

next(error);
Run Code Online (Sandbox Code Playgroud)

你能解释一下他们每个人在Express应用程序环境中会做些什么吗?

例如,这是一个处理URL参数的快速函数:

app.param('lineup_id', function (req, res, next, lineup_id) {
        // typically we might sanity check that user_id is of the right format
        if (lineup_id == null) {
            console.log('null lineup_id');
            req.lineup = null;
            return next(new Error("lineup_id is null"));
        }

        var user_id = app.getMainUser()._id;
        var Lineup = app.mongooseModels.LineupModel.getNewLineup(app.system_db(), user_id);
        Lineup.findById(lineup_id, function (err, lineup) {
            if (err) {
                return next(err);
            }
            if (!lineup) {
                console.log('no lineup matched');
                return next(new Error("no lineup matched"));
            }
            req.lineup = lineup;
            return next();
        });
    });
Run Code Online (Sandbox Code Playgroud)

在评论的行中"//我应该在这里创建自己的错误吗?" 我可以使用"抛出新错误('xyz')",但究竟是什么呢?为什么通常更好地将错误传递给'next'回调?

另一个问题是 - 当我在开发中时,如何在控制台和浏览器中显示"抛出新错误('xyz')"?

Mig*_*nto 15

在回调中抛出错误不起作用:

app.get('/', function (req, res) {
  fs.mkdir('.', (err) => {
    if (err) throw err;
  });
});
Run Code Online (Sandbox Code Playgroud)

但调用 next 有效:

app.get('/', function (req, res, next) {
  fs.mkdir('.', (err) => {
    if (err) next(err);
  });
});
Run Code Online (Sandbox Code Playgroud)


小智 8

一般表示遵循传递错误而不是抛出错误的方式,对于程序中的任何错误,您可以将错误对象传递给"下一个",还需要定义错误处理程序,以便可以处理传递给下一个的所有错误正确

http://expressjs.com/guide/error-handling.html

  • 我通常做的是将错误抛出到 try catch 中,并在 catch 块中调用“next(error)” (3认同)

小智 7

Express 将处理同步代码中引发的所有错误。IE:

app.get('/', function (req, res) {
  throw new Error('My custom thrown Error') // Express will catch this on its own.
})
Run Code Online (Sandbox Code Playgroud)

当异步代码中抛出错误时,您需要告诉express通过将错误传递给下一个函数来处理错误:

app.get('/', function (req, res, next) {
  Promise.resolve().then(() => {
    throw new Error('My custom thrown Error inside a promise')
  }).catch(err => {
    next(err); // Inside async code you have to pass the error to the next function, else your api will crash
  })
})
Run Code Online (Sandbox Code Playgroud)

你必须小心,一旦你使用 async 关键字声明一个函数,该函数的内容就会异步运行:

app.get('/', function (req, res) {
  throw new Error('My custom thrown Error') // Express will catch this on its own.
})
Run Code Online (Sandbox Code Playgroud)
app.get('/', async function (req, res, next) {
  throw new Error('My custom thrown Error') // Express will NOT!! catch this on its own, because it is in an asynchronous function
})
Run Code Online (Sandbox Code Playgroud)

如果您想了解更多信息,请查看文档:https://expressjs.com/en/guide/error-handling.html


小智 5

路由处理程序和中间件内的同步代码中发生的错误不需要额外的工作。如果同步代码抛出错误,Express 将捕获并处理它。例如:

app.get('/', function (req, res) {
  throw new Error('BROKEN') // Express will catch this on its own.
})
Run Code Online (Sandbox Code Playgroud)

  • 如何向此错误添加状态代码?` throw new Error('error', 404)` 不起作用。 (2认同)
  • const err = new Error('错误信息'); 错误.statusCode = 404; 抛出错误; (2认同)