Try/Catch. Под капотом 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...
Хм. поэтому я знаю о попытке/уловке, мой вопрос был сосредоточен на использовании обещаний и их отказе. Насколько я знаю, это не поможет, поскольку они не бросаются в традиционном смысле, а выполняют один из обещаний. Я мог ошибаться, но, насколько я вижу, единственный способ использовать try/catch - это не использовать обещание в этом случае. – David
@David Вы правы, что try/catch не работает с Promises. Но try/catch * does * работает с генераторами. В co-библиотеке используются генераторы + yield, что позволяет использовать try/catch для обнаружения отказов от Promises. Секрет в том, как работают генераторы, и то, как работает работа. – Pauan