【问题标题】:Node.js with Express - throw Error vs next(error)带有 Express 的 Node.js - 抛出错误与下一个(错误)
【发布时间】:2015-01-06 08:26:27
【问题描述】:

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

throw new Error('my error');

或通过通常标记为“下一步”的回调传递此错误,如下所示:

next(error);

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

例如,这里有一个处理 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();
        });
    });

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

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

【问题讨论】:

    标签: node.js express


    【解决方案1】:

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

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

    【讨论】:

    • 我通常做的是在 try catch 中抛出错误并在 catch 块中调用 next(error)
    • 如果有人对此网页的英文版感兴趣:expressjs.com/en/guide/error-handling.html
    • 我按照 ExpressJS 文档开发了一个 npmjs 库,它实现了 HTTP 错误的基本处理,类似于 restify 方式。 (例如next(new BadRequestError('message here')))。我希望它有用。 npmjs.com/package/@acruzjr/express-http-errorsnpm i @acruzjr/express-http-errors
    【解决方案2】:

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

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

    但调用 next 有效:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 如何在此错误中添加 statusCode? throw new Error('error', 404) 不起作用。
      • const err = new Error('错误信息'); err.statusCode = 404;抛出错误;
      【解决方案4】:

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

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

      【讨论】:

      • Invalid or unexpected token @ 当函数在类中时。
      猜你喜欢
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 2017-09-23
      • 1970-01-01
      • 2012-10-28
      • 2021-05-15
      • 1970-01-01
      相关资源
      最近更新 更多