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

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

谁能解释一下在 node.js Express 应用程序中什么时候抛出这样的错误是合适的:

throw new Error('my error');

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

next(error);

能否请您解释一下他们每个人在 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();
        });
    });

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

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

一般express都是采用传递错误而不是抛出错误的方式,对于程序中的任何错误都可以将错误对象传递给'next',同时还需要定义一个错误处理程序,以便所有的传递给 next 的错误可以得到妥善处理

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

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

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

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

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

但调用下一个有效:

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

对于那些喜欢抛出错误的人,这里有一个变通的装饰器:

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' }
}