next() 承诺错误处理

Posted

技术标签:

【中文标题】next() 承诺错误处理【英文标题】:next() promise error handling 【发布时间】:2015-07-29 03:46:02 【问题描述】:

错误处理的最佳方式是什么? 我需要自定义 json 错误消息。这是一个 API。

exports.putCurso = function (req, res, next) 
    util.updateDocument(req.curso, Curso, req.body);
    req.curso.saveAsync()
        .then(function (data) 
            return res.status(201).json(message: 'Curso atualizado.', data: data);
        )
        .catch(function(error) 
            return res.status(500).json(message: 'ERROR!');
            //OR return next(error); but I need custom json error messages so it doesn't make sense
        )
        .finally(next); //OR return next(error)? redundant?
;

【问题讨论】:

Curso 与哪个实例相关?是猫鼬文档吗? 理想情况下,您可以从链中return 并让next 调用它。我不确定这需要什么样的快递。 【参考方案1】:

我不是猫鼬,但我知道一两件事关于表达和承诺

exports.putCurso = function (req, res, next) 
  util.updateDocument(req.curso, Curso, req.body);
  req.curso.saveAsync()
      .then(function (data) 
        res.status(201).json(message: 'Curso atualizado.', data: data);
      , function(error)
        res.status(500).json(message: 'ERROR!');
      )
;

这基本上就是您所需要的。根据实现,这可能是一条正常的路由,因为它总是向客户端返回一些东西(res.json)。因此,您不必调用next,因为它是供中间件调用的

你也不必返回任何东西,因为当你调用 res.json 时,它基本上说这个请求在这里结束,没有别的。

最后但同样重要的是,根据规范,promise then 支持 2 个功能,第一个用于处理成功案例,第二个用于处理异常。所以,你不必打电话给catch

【讨论】:

也就是说 catch() 仅在链接承诺时有用?那么,catch 是否只是为了便于阅读? 是的,是的。通常,您将使用done 来指示链的结束,并使用catch 来处理异常。请注意,您可以使用多个流行语来处理不同类型的异常(基于每个异常的“类”)【参考方案2】:

asCallback 接受一个回调,它调用的承诺结果映射到回调约定:

如果 promise 被拒绝,它会以错误作为第一个参数调用回调:cb(error)

如果实现了承诺,它会调用回调,并将值作为第二个参数:cb(null, value)

exports.putCurso = function (req, res, next) 
    util.updateDocument(req.curso, Curso, req.body);
    req.curso.saveAsync()
        .then(function (data) 
            return res.status(201).json(message: 'Curso atualizado.', data: data);
        )
        .catch(function(error) 
            return res.status(500).json(message: 'ERROR!');
            //OR return next(error); but I need custom json error messages so it doesn't make sense
        )
        .asCallback(next);
;

【讨论】:

假设这个putCurso是一个中间件,既然我们已经把数据(res.json)返回给客户端了,为什么还要next呢? 我不知道,我只是说如何使用promises xD【参考方案3】:

考虑Curso一个猫鼬文件 你可以这样做

    req.curso.save(function(err,data)
      if(err) res.status(500).json(message: 'ERROR!');
      else res.status(201).json(message: 'Curso atualizado.', data: data)
    );

编辑:如果你在你的小节点应用程序中有这么多类似的问题,它值得一看rb,那么你可以这样做

var RB = require('rb');
exports.putCurso = function (req, res, next) 
    util.updateDocument(req.curso, Curso, req.body);
    // the below line could have been written in some middleware (eg middleware provided by express.io), so we do get clear code in controller part.
    res.RB = RB.build(res,   // you may customize your builder yours way, after looking into `rb` docs
      errorStatus : 500, successStatus : 201,
      errorKey : false, successKey : 'data',
      preProcessError : function() return  message : 'ERROR!'  ,
      addToSuccess :  message : 'Curso atualizado.' 
    );

   //Now only one line in controller
   req.curso.save(res.RB.all);
;

披露:我是rb的作者。

【讨论】:

以上是关于next() 承诺错误处理的主要内容,如果未能解决你的问题,请参考以下文章

处理快递申请中未处理的承诺拒绝

javascript 承诺所有运行所有承诺和处理程序错误

未要求承诺的错误处理程序

expressjs 承诺和 sunc 错误处理

Firebase 函数 tslint 错误 必须正确处理承诺

Axios 承诺处理 - 在 react-native 中获取“可能的未处理承诺拒绝 - 类型错误:网络请求失败”