5

我有一个使用 swagger 与 node.js 上的 express 集成的 API,以及一个定义如下的资源。在检查 (!req.params.id) 时抛出的 swagger 错误被 swagger 的默认错误处理程序捕获。未捕获 mongoDB 删除调用的回调中引发的错误,给我以下错误。该错误看起来与回调函数的范围/顺序有关,作为 node.js 的新手,我希望获得有关如何正确执行此操作的建议,以保持异步性。-谢谢

events.js:74 throw TypeError('Uncaught, unspecified "error" event.'); ^ TypeError:未捕获的、未指定的“错误”事件。

exports.remove = {
    'spec' : {
      "collapsed...for...brevity..." : "...",
      "params" : [ {
        "paramType" : "path",
        "name" : "id",
        "collapsed...for...brevity..." : "...",
      }],
      "errorResponses" : [ swe.notFound('id'), swe.invalid('id') ],
      "nickname" : "remove"
    },
    'action' : function(req, res) {

      if (!req.params.id) {
        throw swe.invalid('id');   // THIS ERROR IS CAUGHT
      }

      req.coll.remove({_id : req.coll.id(req.params.id)}, function(e, result) {
        if (e) {
          throw swe.invalid('collection');   // THIS ERROR IS NOT CAUGHT
        }

        res.send({msg : 'success'});
      });
    }
  };
4

3 回答 3

6

在异步回调中抛出的异常会转到回调的调用者,而不是您的周围代码。所以它req.coll.remove是接收异常的代码(它没有处理它)并使你的应用程序崩溃。

相反,您需要让您的 removeaction函数接受一个回调参数,该参数可用于将错误传回给调用者。

这就是为什么在 node.js 代码中很少使用异常并且回调是标准的原因。

于 2013-11-14T17:11:02.057 回答
5

规则 1. 不要抛出回调。最好不要扔。仅当您希望进程崩溃时才抛出。如果您需要将错误传递给调用者,请使用callback(err). 如果您在 connect/express 中间件范围内,您也可以使用next(err).

规则 2。如果仍然抛出某些东西并且您想抓住它,请使用domain。以这种方式考虑规则 1,您只能捕获超级意外的事情,因此您必须尽快取消该过程。

于 2013-11-14T17:25:54.130 回答
1

不要使用回调,而是使用承诺并在承诺链中抛出异常......

var P = require('bluebird');

// ...

return new P(function(resolve, reject) {
  req.coll.remove({_id : req.coll.id(req.params.id)}, function(e, result) {
    if (e) {
      reject(swe.invalid('collection'));   // THIS ERROR will be CAUGHT
    }
    resolve(res.send({msg : 'success'}));
  });
})
.catch(function(err) {
  throw err;
});
于 2016-05-01T05:58:11.160 回答