2014-09-24 4 views
2

Я использую Firefox 32 и Chrome 37 с Mithril.js и теперь неоднократно спотыкался опечатками в именах переменных, просто заставляя JS прекращать выполнение в точке ссылки. Это особенно неприятно для меня, исходя из C и Java, поскольку я привык к тому, что компилятор ловил такие тривиальные ошибки, прежде чем я даже попытаюсь запустить код.ReferenceError изнутри Цепочка обещаний Мифрила молча игнорируется

я сузил проблему, происходит только в функциях работает как часть посыла цепи AJAX, как это:

function getListData(ctl) { 
    ctl.data([]); 
    ctl.loading(true); 
    return m.request({ method: "GET", url: apiBase, background: true }).then(done,fail); 

    function done(rspdta) { 
     xctl.loading(false); 
     ctl.data(rspdta.Customer); 
     m.redraw(); 
     }; 

    function fail(rspdta) { 
     ctl.loading(false); 
     ajaxError(ctl); 
     m.redraw(); 
     throw rspdta;                    // continue error condition 
     }; 
    } 

Обратите внимание, в функции done намеренное xctl.loading(false) - сценарий просто, как представляется, остановитесь там, но бросьте ReferenceError. Однако ничего не регистрируется.

Я работаю на том, чтобы доказать доказали, что это поимки и игнорируется Mithril.js сейчас, в этом коде:

function thennable (ref, cb, ec, cn) { 
    if ((typeof val == 'object' || typeof val == 'function') && typeof ref == 'function') { 
     try { 

      // cnt protects against abuse calls from spec checker 
      var cnt = 0 
      ref.call(val, function (v) { 
       if (cnt++) return 
       val = v 
       cb() 
      }, function (v) { 
       if (cnt++) return 
       val = v 
       ec() 
      }) 
     } catch (e) { 
      /**/console.log("[**] Caught in thennable: %o",e); 
      val = e 
      ec() 
     } 
    } else { 
     cn() 
    } 
}; 

Надеюсь, кто-то из этого сообщества будет в состоянии сказать, имею ли я что-то не так, неправильно использую цепочку обещаний (??) или если это ошибка в Mithril.js 0.1.21.

+0

Можете указать, что опечатка в вашем коде выше? Я ничего не замечаю с такими короткими/запутывающими именами – Ian

+0

@Ian: Код выше правильный, извините, если это вводит в заблуждение - я показывал структуру кода с '' use strict '', в результате чего я ожидаю, что он даст ошибка для необъявленных 'var'. Просто изменить любой 'rspdta', скажем,' rpsdta', достаточно, чтобы скрипт просто прекратил выполнение в этот момент. Это почти так, как если бы исключение было выброшено, попавшее в цикл событий, но не сообщается. –

+0

Ну, тогда я смущен вашей проблемой. Если я не ошибаюсь, нет ничего плохого в отношении ** доступа к ** «неопределенным» переменным (поскольку они могут быть глобальными). ** Установка ** неопределенных переменных не допускается в строгом режиме. Это то, о чем вы думаете? – Ian

ответ

2

Короче говоря, это проблема в Обещания/A + спецификации (в основном это не делает различий между проверенными и непроверенными ошибками). Для Мифрила 0.1.21 (и в этом отношении для собственных ES6 Promises) обходной путь, чтобы поймать ошибку, - это сделать то, что сказал Золмейстер.

.then(buggyCallback) //this throws the ReferenceException 
.then(null, function(e) {console.error(e)}) 

В качестве альтернативы, Mithril 0.1.19 (последняя версия перед PR слияния Promiz) бросает на консоль по умолчанию.

Mithril 0.1.22 будет поставляться с монитором исключений для обещаний, который позволит вам настроить, как выполнять ранние исключения на обещание (и будет по умолчанию бросать на консоль ошибки программиста). Вы можете найти эту версию в репозитории разработки.

+0

Насколько я понимаю, что ошибки, такие как ReferenceError, будут консольным журналом по умолчанию в следующей версии? С трассировкой стека? Если это так, это прекрасно. –

+0

Является ли 0.1.22 достаточно стабильным для использования в производстве? –

+0

После переваривания ответа на [к моей проблеме в github] (https://github.com/lhorie/mithril.js/issues/279), я считаю, что недостающее в Mithril - это своего рода механизм «finally». Но я согласен с Raynos в этом потоке, что вы не можете технически знать, что исключение не обрабатывалось до тех пор, пока обещание не GC'd, потому что какой-то асинхронный код может присоединить обработчик в любой момент. В то же время, в любом контексте, беззвучно усваиваемые и необработанные исключения ужасны. Тем не менее, по-прежнему кажется, что ошибки из-за ошибок кодирования всегда должны регистрироваться, когда они обнаружены. –

1

Ошибки, сброшенные внутри обработчика onFulfilled, приводят к отклонению обещаний. Spec: http://promisesaplus.com/#point-42

Вот решение:

abc.then(thrower, fail1).then(null, fail2) 

Он будет пойман fail2

+0

Я бы согласился на общее намеренно исключенное исключение из кода пользователя/библиотеки, но для механизма JavaScript * Ошибка *, я думаю, что их нужно обрабатывать и повторять. В качестве теста в предложениях Mithrils 4 'catch' я добавил catch и rethrow для' Error', а конечным результатом была консольная ошибка с строкой * my *, где была опечатка. Разве вы не думаете, что это было бы правильнее? –

+0

Это решение, похоже, должно предусматривать возможность того, что я могу вызвать ошибку JS (ReferenceError, RangeError и т. Д.) И *** во всем мире *** Я должен добавить другой обработчик, что ?, перестроить ошибку? –

Смежные вопросы