dfilatov/vow

Throw exception from last callback

Closed this issue · 21 comments

Example:

doRequest.then(function() {
   throw new Error('error');
});

doRequest.fulfill(); // should throw exception

Seems like an obvious bug. Why not fix it?

В других подобных библиотеках, например Q, как раз исправили то поведение, которое вы просите, на то, которое есть в данный момент.
Если нужно, чтобы exception вышел за пределы цепочки промисов, то нужно делать done в конце цепочки.

Это очевидно некорректное поведение. Эксепшены, кидаемые из пользовательского кода должны прозрачно проходить наружу, с чего вдруг фреймворк промисов берёт на себя функцию их обработки?
Почему в Q так сделали, я не знаю.

Все обработчики завернуты в try/catch (смотри спецификацию Promises A+), прям совсем прозрачно оно не может выходить наружу по определению. Эксепшен можно только перевбрасывать на выходе.

Значит, надо перевыбрасывать на выходе.

В этом и вопрос, надо или нет. И почему никто так не делает, а делают явное завершение цепочки с помощью done.

Не знаю, почему так не делают. Но это же упячка:

try {
promise.then(function () {
throw new Error();
}
} catch (e) {
// хрен
}

Это (а) неконсистентно, при замене на колбэки всё станет ок, (б) заставляет знать о внутреннем устройстве промиса, (в) логически криво - с чего вдруг промис ловит ошибку, ему не предназначенную, да ещё и грохает её. Т.о. к обработчику onFulfill на самом деле предъявлено сильное ограничение (он не имеет права использовать часть возможностей языка), что логически неочевидно и ниоткуда не вытекает.

Ну твой пример невозможно заставить работать в принципе, учитывая что колбэки всегда вызываются асинхронно.

Ну ок, перепиши его на window.onerror или domains api

ну это как бы не тоже самое, не находишь?

нет никаких ограничений к onFulfill, есть требование, что если тебе нужны выбросы эксепшенов, то тебе нужно завершать цепочку с помощью done.

Блин. Я хочу работать с промисами как с заменой callback-ам, а не неведомой магией. Что за проблема с эксепшенами, я не могу понять?

А в чем проблема писать обработчики ошибок в onRejected и почему вы их не пишете? )

Я попробую, в ближайшем будущем, в вашей ветке для ymaps api, сделать такое поведение.

The Golden Rule of done vs. then usage is: either return your promise to someone else, or if the chain ends with you, call done to terminate it.

В том, что onRejected не предназначен для обработки ошибок в onFulfilled.
Ты хочешь сказать, что бросание exception-а из onFulfill эквивалентно реджекту промиса? о_О

Бросание exception-а из onFulfill приводит к режекту промиса, который возвращает then. В спецификации это написано английским по-белому.

o_O и правда
http://dom.spec.whatwg.org/#promises
Ну тогда остаётся смириться. Херня какая-то.

в этой спецификации вообще явно написано:
The exception is not re-thrown and does not reach window.onerror.

Угу. Пичаль-бида, короче. Придётся с этим жить.

Ну тогда won't fix, сорри )