Обработка ошибок с обещаниями в Koa

Если я даю обещания в Коа, они могут быть отвергнуты:

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

Есть ли в Koa шаблон обработки ошибок, чтобы справиться с этим, помимо явного развертывания обещания с помощью then и явной обработки ошибки?


person David    schedule 14.04.2015    source источник


Ответы (2)


Попробуйте поймать. Под капотом 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');
}

Вот элементарный пример того, что происходит с обещанием:

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...
person James Moore    schedule 14.04.2015
comment
Хм... так что я знаю о поведении try/catch, мой вопрос был сосредоточен на использовании обещаний и их отклонении. Насколько я знаю, это не поможет, так как они не бросают в традиционном смысле, а скорее выполняют один из обратных вызовов обещаний. Я могу ошибаться, но, насколько я понимаю, единственный способ использовать try/catch — это не использовать промис в данном случае. - person David; 14.04.2015
comment
@David Вы правы, что try/catch не работает с Promises. Но try/catch работает с генераторами. Библиотека co использует генераторы + yield, что позволяет вам использовать try/catch для перехвата отклонений от промисов. Секрет в том, как работают генераторы и как работает доходность. - person Pauan; 04.01.2016

Вы можете легко добавить пакет koa-better-error-handler с npm 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

person niftylettuce    schedule 03.08.2017