【问题标题】:Error handling with promises in Koa在 Koa 中使用 Promise 处理错误
【发布时间】:2015-06-19 11:01:45
【问题描述】:

如果我在 Koa 中产生 promise,它们可能会被拒绝:

function fetch = (){
  var deferred = q.defer(); 
  //Some async action which calls deferred.reject();
  return deferred.promise;
}

this.body = yield fetch(); //bad, not going to work

除了用then 显式解开promise 并显式处理错误之外,Koa 中是否有一个错误处理模式来处理这个问题?

【问题讨论】:

    标签: node.js koa


    【解决方案1】:

    尝试/抓住。在后台koajs 使用co。查看 co 的文档,它更好地描述了错误处理。

    function fetch = (){
      var deferred = q.defer(); 
      //Some async action which calls deferred.reject();
      return deferred.promise;
    }
    try{
        this.body = yield fetch(); //bad, not going to work
    }
    catch(err){
        this.throw('something exploded');
    }
    

    这是一个关于 promise 的基本示例:

    function * someGenerator () {
      let result;
      try{
        result = yield fetch();
        console.log('won\'t make it here...');
      }
      catch(err){
        console.log(err);
      }
      console.log('will make it here...');
    }
    // Normally co() does everything below this line, I'm including it for
    // better understanding
    
    // instantiate the generator
    let gen = someGenerator();
    // calling gen.next() starts execution of code up until the first yield
    // or the function returns.  
    let result = gen.next();
    // the value returned by next() is an object with 2 attributes
    // value is what is returned by the yielded item, a promise in your example
    // and done which is a boolean that indicates if the generator was run 
    // to completion
    // ie result = {value: promise, done: false}
    
    // now we can just call the then function on the returned promise
    result.value.then(function(result){
      // calling .next(result) restarts the generator, returning the result
      // to the left of the yield keyword
      gen.next(result);
    }, function(err){
      // however if there happened to be an error, calling gen.throw(err)
      // restarts the generator and throws an error that can be caught by 
      // a try / catch block.  
      // This isn't really the intention of generators, just a clever hack
      // that allows you to code in a synchronous style (yet still async code)
      gen.throw(err);
    });
    

    如果您仍然不确定,这里有几件事可能会有所帮助:

    在此处观看我关于 JavaScript 生成器的截屏视频:http://knowthen.com/episode-2-understanding-javascript-generators/

    和/或尝试以下代码:

    // test.js
    'use strict';
    let co      = require('co'),
        Promise = require('bluebird');
    
    function fetch () {
      let deffered = Promise.defer();
      deffered.reject(new Error('Some Error'));
      return deffered.promise;
    }
    
    co.wrap(function *(){
      let result;
      try{
        result = yield fetch();
        console.log('won\'t make it here...');
      }
      catch(err){
        console.log(err);
      }
      console.log('will make it here...');
    
    })();
    

    然后在控制台运行

    $ node test.js
    [Error: Some Error]
    will make it here...
    

    【讨论】:

    • 嗯..所以我知道 try/catch 行为,我的问题集中在承诺的使用及其拒绝。据我所知,这无济于事,因为它们不是传统意义上的投掷,而是履行承诺回调之一。我可能是错的,但据我所知,使用 try/catch 的唯一方法是在这种情况下使用 Promise。
    • @David 你说得对,try/catch 不适用于 Promises。但是 try/catch 确实 与生成器一起工作。 co 库使用 generators + yield,它允许您使用 try/catch 来捕获来自 Promises 的拒绝。秘诀在于生成器的工作方式以及 yield 的工作方式。
    【解决方案2】:

    您可以轻松地将koa-better-error-handlernpm install --save koa-better-error-handler 放入包中,然后这样实现它:

    const errorHandler = require('koa-better-error-handler');
    
    // override koa's undocumented error handler
    app.context.onerror = errorHandler;
    

    更多信息:https://github.com/niftylettuce/koa-better-error-handler

    【讨论】:

      猜你喜欢
      • 2018-08-20
      • 2014-12-15
      • 2014-06-21
      • 1970-01-01
      • 2019-02-17
      • 2017-10-26
      • 2021-06-05
      • 2016-09-29
      • 2023-03-29
      相关资源
      最近更新 更多