Как отлаживать мой асинхронный, основанный на обещании код, если библиотека поглощает все исключения?

Проблема

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) ничего не отображает, но нечетное отклонение появляется на консоли после завершения кода.