Хорошо, я могу просто пропустить очевидное, но я не могу найти общий ответ на этот вопрос, и мой Google-Fu до сих пор мне не удалось.Bluebird (или другая библиотека Promise) Сохраняйте следы следов ошибок Promise
В обработчике Catch Promise, как вы перебрасываете ошибку, сохраняя при этом трассировку стека Promise исходной ошибки?
Это, возможно, не правильное описание, так вот пример:
https://jsfiddle.net/8sgj8x4L/19/
С помощью этого кода, то прослеживается стек:
Warning: a promise was rejected with a non-error: [object String]
at RejectWithAnError (https://fiddle.jshell.net/_display/:51:19)
at https://fiddle.jshell.net/_display/:57:14
From previous event:
at StartTheProgram (https://fiddle.jshell.net/_display/:56:6)
at window.onload (https://fiddle.jshell.net/_display/:67:1)
bluebird.js:1444 Unhandled rejection an error occurred
Однако, если обработчик Загвоздка добавлена, и ошибка будет повторно отвергнута или повторно выбрана из этого обработчика, тогда стек станет местом нового вызова метода отклонения:
https://jsfiddle.net/8sgj8x4L/18/
Какие следы этой трассировки стека:
Warning: a promise was rejected with a non-error: [object String]
at https://fiddle.jshell.net/_display/:65:23
From previous event:
at StartTheProgram (https://fiddle.jshell.net/_display/:61:11)
at window.onload (https://fiddle.jshell.net/_display/:70:1)
bluebird.js:1444 Unhandled rejection an error occurred
Вы можете увидеть внутренний метод, который переданную первоначальную ошибку, «RejectWithAnError», исчезает из второго стека, так как была поймана ошибка и вновь брошен.
Для справки, вот полный код из JSFiddle (Новейший Bluebird упоминается в качестве внешней зависимости):
window.P.longStackTraces();
function RejectWithAnError() {
var err = {error: true, message: "an error occurred"};
err.prototype = new Error();
return window.P.reject(err);
}
function StartTheProgram() {
return RejectWithAnError()
// Comment out this catch handler completely, and the Promise stack trace will correctly show the "RejectWithAnError" method as the error origin.
.catch(function (status) {
console.log("[WARN] Catch handler was called.");
// Neither of these lines will show "RejectWithAnError" in the Promise chain stack trace.
// throw status;
return window.P.reject(status);
});
}
StartTheProgram()
(На стороне записки, это мой первый Stack Overflow вопрос, так что я надеюсь, что это правильный формат для этого вопроса.)
Редактировать: Обновлен пример отказа от использования экземпляра объекта, который наследуется от нового экземпляра Error
.
Sidenote: Всегда отклонять экземпляр конструктора 'Error'. –
'status' является строкой и не может хранить информацию о стеке. Вот почему вы всегда должны использовать объекты 'Error'. – Bergi
Спасибо за указатель. Я обновил JSFiddle, чтобы использовать экземпляр Error: [https://jsfiddle.net/8sgj8x4L/12/](https://jsfiddle.net/8sgj8x4L/12/) Исходная трассировка стека определенно полезна, в идеале было бы сохранить цепочку обещаний, которая привела бы к ошибке через сложные цепочки обещаний. Например, при включении длинных стеков в Bluebird вы можете увидеть все обещания, которые привели к сбою, но если я добавлю обработчик catch, он, похоже, потеряет любую информацию, прежде чем этот обработчик улова будет вызван в Promise цепь. –