带有 Express 的 Node.js - 抛出错误与下一个(错误)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27794750/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 18:16:46  来源:igfitidea点击:

Node.js with Express - throw Error vs next(error)

node.jsexpress

提问by Alexander Mills

Can someone expound on the times when it's appropriate in a node.js Express app to throw an error like so:

有人可以解释一下在 node.js Express 应用程序中何时适合抛出这样的错误:

throw new Error('my error');

or to pass this error on via the callback usually labelled 'next' like so:

或者通过回调传递这个错误,通常标记为“next”,如下所示:

next(error);

and could you please explain what each of them will do in the context of an Express app?

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

for example, here is an express function dealing with URL parameters:

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

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();
        });
    });

In the line commented "//should I create my own error here?" I could used "throw new Error('xyz')", but what exactly would that do? Why is it usually better to pass the error to the callback 'next'?

在注释“//我应该在这里创建自己的错误吗?”的行中 我可以使用“throw new Error('xyz')”,但那究竟会做什么呢?为什么通常将错误传递给回调“next”更好?

Another question is - how do I get "throw new Error('xyz')" to show up in the console as well as the browser when I am in development?

另一个问题是 - 在开发过程中,如何让“throw new Error('xyz')”显示在控制台和浏览器中?

采纳答案by Arjun

In general express follows the way of passing errors rather than throwing it, for any errors in the program you can pass the error object to 'next' , also an error handler need to be defined so that all the errors passed to next can be handled properly

一般来说,express 遵循传递错误而不是抛出错误的方式,对于程序中的任何错误,您可以将错误对象传递给 'next' ,还需要定义一个错误处理程序,以便可以处理传递给 next 的所有错误适当地

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

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

回答by Miguel Pynto

Throwing an error inside a callback doesn't work:

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

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

But calling next works:

但是调用 next 有效:

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

回答by Oleg Khalidov

For those who prefer throwing errors, here is a workaround decorator:

对于那些喜欢抛出错误的人,这里有一个解决方法装饰器:

export function safeThrow(
    target: object,
    key: string | symbol,
    descriptor: TypedPropertyDescriptor<(req: Request, res: Response, next: NextFunction) => Promise<any>>) {
    const fun = descriptor.value;
    descriptor.value = async function () {
        try {
            await fun.apply(this, arguments);
        } catch (err) {
            arguments[2](err);
        }
    };
}

@safeThrow
private async get(req: Request, res: Response, next: NextFunction) {
  throw { status: 404, message: 'Not supported' }
}

回答by eric_cartman

Errors that occur in synchronous code inside route handlers and middleware require no extra work. If synchronous code throws an error, then Express will catch and process it. For example:

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

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