Отлов ошибок, сгенерированных в промисах внутри промисов в JavaScript

Возможно ли, чтобы ошибки всплывали в промисах?

См. приведенный ниже код для справки, я хотел бы получить promise1.catch, чтобы поймать ошибку, сгенерированную в promise2 (какой ток не работает с этим кодом):

function test() {
    var promise1 = new Promise(function(resolve1) {
        var promise2 = new Promise(function(resolve2) {
            throw new Error('Error in promise2!');
        });

        promise2.catch(function(error2) {
            console.log('Caught at error2', error2);
        });
    });

    promise1.catch(function(error1) {
        console.log('Caught at error1', error1);
    });
}

test();

person Kirk Ouimet    schedule 30.07.2014    source источник
comment
Просто не вставляйте конструкторы Promise. Для этого нет абсолютно никаких причин. Чего вы пытаетесь достичь?   -  person Bergi    schedule 30.07.2014
comment
Кроме того, выполните re-throw error2 в обработчике catch и resolve1() внешнее обещание вместе с ним.   -  person Bergi    schedule 30.07.2014


Ответы (1)


Да!!

Распространение ошибок в промисах — одна из его сильных сторон. Он действует точно так же, как в синхронном коде.

try { 
    throw new Error("Hello");
} catch (e){
    console.log('Caught here, when you catch an error it is handled');
}

Очень похоже на:

Promise.try(function(){
    throw new Error("Hello");
}).catch(function(e){
    console.log('Caught here, when you catch an error it is handled');
});

Так же, как и в последовательном коде, если вы хотите выполнить какую-то логику для ошибки, но не помечать ее как обработанную, вы повторно выдаете ее:

try { 
   throw new Error("Hello");
} catch (e){
    console.log('Caught here, when you catch an error it is handled');
    throw e; // mark the code as in exceptional state
}

Что становится:

var p = Promise.try(function(){
   throw new Error("Hello");
}).catch(function(e){
    console.log('Caught here, when you catch an error it is handled');
    throw e; // mark the promise as still rejected, after handling it.
});

p.catch(function(e){
     // handle the exception
});

Обратите внимание, что в Bluebird у вас могут быть типизированные и условные перехваты, поэтому, если все, что вы делаете, это if для типа или содержимого промиса, чтобы решить, обрабатывать его или нет - вы можете сохранить это.

var p = Promise.try(function(){
   throw new IOError("Hello");
}).catch(IOError, function(e){
    console.log('Only handle IOError, do not handle syntax errors');
});

Вы также можете использовать .error для обработки OperationalError, которые происходят из обещанных API. В общем случае OperationalError означает ошибку, от которой можно избавиться (в отличие от ошибки программиста). Например:

var p = Promise.try(function(){
   throw new Promise.OperationalError("Lol");
}).error(function(e){
    console.log('Only handle operational errors');
});

Преимущество этого заключается в том, что в вашем коде не замалчиваются TypeError или синтаксические ошибки, которые могут раздражать в JavaScript.

person Benjamin Gruenbaum    schedule 30.07.2014