Как отлаживать мой асинхронный, основанный на обещании код, если библиотека поглощает все исключения?
Проблема
JSFiddle:
http://jsfiddle.net/missingno/Gz8Pe/2/
У меня есть код, который выглядит так:
var d = new Deferred();
d.resolve(17);
return d.then(function(){
//do some stuff...
})
.then(function(){
var obj = a_funtion_that_returns_null_on_IE();
var x = obj.some_property; //BOOM!
});
Проблема в том, что когда я нахожусь в IE, все, что я вижу, это 'obj' is null or not an object
errors, без ссылки на соответствующий номер строки и без отладки, останавливающейся на нарушающей строке (например, я хочу это было бы).
Такая проблема делает код причиной отладки и единственными решениями, о которых я могу думать прямо сейчас (возиться с библиотекой потока управления или прибегать к пошаговой отладке с помощью отладчика или console.log) вещи, которые я бы предпочел не делать.
То, что я думаю, происходит
Для того, чтобы добавить адвенчуры после запуска цепочки, then
будет упреждать любые исключения, вызванные обратными вызовами. Я думаю, что это причина того, что отладчик IE не останавливается на ошибке или показывает обычное сообщение об ошибке с номером строки в нем.
Сообщения об ошибках без номеров строк поступают из библиотеки потока управления: он предоставляет крюк deferredOnError
, который вызывается всякий раз, когда исключение поймано и сохраняется позже, а поведение по умолчанию - console.error-ing the Error объект:
dojo.config.deferredOnError = function(err){
//a chance to log the exception after it is captured by "then"
//or do other things with it
console.error(err);
}
К сожалению, я не мог понять, как получить номер строки или трассировку стека от объекта ошибки в IE, и крюк вызывается таким образом, который не позволяет мне просто перестроить исключение и позволить ему закрашиваться до toplevel.
Что я хочу
Я хочу иметь лучший способ для отладки асинхронного кода, а затем шаг за шагом отладчика. В лучшем случае можно отключить отладчик на исключениях (как и при необработанных исключениях) или, по крайней мере, способ получить номера строк или стек трассировки из объекта Error, который был брошен.
Ответы
Ответ 1
Это работает с любой инфраструктурой без предварительной настройки, и все последние браузеры поддерживают это.
Пауза на выведенных исключениях: Это фактически остановит выполнение javascript и проведет вас именно там, где проблемный код как это происходит.
![Pause On Caught Exceptions]()
В Chrome:
- Инструменты разработчика,
- вкладка Источники,
- Пауза на исключения (значок стоп-кадра), а затем
- флажок Приостановить снятые исключения
Ответ 2
Что я закончил делать
Я добавил функцию секвенирования в мини-библиотеку вспомогательных функций async. Он в основном выполняет последовательность "затем" вызовов, за исключением того, что он добавляет дополнительные промежуточные шаги для реконструирования любых исключений, которые в конечном итоге попадают в "Отложенные". Он также принимает необязательный обработчик ошибок для исключения исключений.
Когда я его вызываю, он выглядит так:
go([
function(){
return 17;
},
function(x){
//return some stuff
},
function(){
var obj = a_function_that_returns_null_on_IE();
var x = obj.some_property; //BOOM!
}
], function(){
//an optional error handler
});
Еще одна причина, по которой я так делал, заключается в том, что у меня есть много кода, который должен работать одновременно с синхронизацией или асинхронным кодом (используя Deferred.when для создания цепочки). Используя мою пользовательскую функцию, позвольте мне использовать единый унифицированный синтаксис, а ошибки, которые не записываются в асинхронном случае, соответствуют случаю синхронизации, в котором нет отложенных событий. Я также думаю, что это нормально, чтобы не зафиксировать ошибку, поскольку, в отличие от общего случая, когда я использую "go", я знаю априори, какой код будет вызываться, поэтому нет необходимости фиксировать исключения, если кто-то должен поймать их в будущем.
Кроме того, использование пользовательского решения дало мне свободу для выполнения некоторых личных дизайнерских предпочтений:)
В дополнение к этому, я закончил тем, что уменьшил количество исключений, которые я генерирую во всей базе кода. Управление исключениями в асинхронном коде более раздражает, чем обычно, а иногда и проще, чем просто возврат к обработке ошибок, возвращая null или код ошибки.
Кроме того, мы убедились, что любые исключения, которые мы создаем сами, являются экземплярами встроенного класса Error, а также для других объектов. Причина в том, что встроенный класс ошибок записывает номер строки и трассировку стека, где он был сгенерирован в виде кросс-браузера.
Ответ 3
2016 решение
Если вы используете собственный ES Promises, ничего не делайте; Chrome автоматически сообщает о нечетких обещаниях в консоли.
![]()
Обратите внимание, что пойманный (Second fail
) ничего не отображает, но нечетное отклонение появляется на консоли после завершения кода.