Я использую библиотеку RSVP, распространяемую внутри Ember.js, и пытаюсь выяснить правильный шаблон для сообщения о фатальных ошибках внутри обещания — в частности, я хочу сообщить о чем-то, что почти наверняка является результатом ошибки программирования из-за неправильное использование API, и я хочу сделать это ГРОМКО. Я новичок в обещаниях и javascript в целом, надеюсь, этот вопрос имеет смысл
Вот простой пример (в coffeescript):
doAsync = (arg, callback) ->
throw new Error('you gave me a way bad arg, I fail for you!')
promiseReturningApi = (data) ->
return new Ember.RSVP.Promise (resolve, reject) ->
callback = (err, resp) ->
if err then reject(err)
else resolve(resp)
doAsync(data, callback)
Теперь предположим, что я обнаружил ошибку, которую невозможно исправить, и которая произошла внутри doAsync. Я хочу убедиться, что об этой ошибке будет сообщено, даже если вызывающая сторона забыла прикрепить обработчик ошибок, потому что она почти наверняка возникла только потому, что вызывающий абонент неправильно вызвал функцию API
Я столкнулся с идеей использования setTimeout в обработчике отклонения, чтобы гарантировать, что ошибка возникает откуда-то, даже если вызывающая сторона не прикрепляет обработчик ошибок к обещанию.
failLoud = (err) ->
if err.isProgrammerError
setTimeout () ->
throw err
throw err
promiseReturningApi = (data) ->
promise = new Ember.RSVP.Promise (resolve, reject) ->
callback = (err, resp) ->
if(err) then reject(err)
else resolve(resp)
doAsync(data, callback)
return promise.then(null, failLoud)
Считается ли разумной практикой прикреплять такой обработчик ошибок по умолчанию к обещанию перед его возвратом из моего promiseReturningApi? Это позволило бы мне форсировать трассировку стека, когда вызывающая сторона делает что-то, что не может работать - даже если трассировка стека была бы немного странной, это могло бы немного облегчить начало работы...
Несмотря на то, что я назвал функцию, возвращающую промис, вызовом API — я должен добавить, что я не пишу код фреймворка — скорее все это внутри приложения. Если бы doAsync была реальной функцией, то в моей версии реального мира она, скорее всего, исходила бы от внешней стороны с новым для меня API, так что вполне вероятно, что я буду использовать ее неправильно, пока Я узнаю это ... Это означает, что я мог бы захотеть сделать шаблон примерно таким
failLoud = (err) ->
if err?.isProgrammerError
setTimeout () ->
throw err
throw err
promiseReturningApi = (data) ->
promise = new Ember.RSVP.Promise (resolve, reject) ->
callback = (err, resp) ->
if(err) reject(err)
resolve(resp)
try
doAsync(data, callback)
catch err
err.isProgrammerError = true
throw err
return promise.then(null, failLoud)
Я думаю, что это принудительно вызывает исключение из где-то каждый раз, когда мой асинхронный вызов функции сам вызывает исключение - такое исключение почти наверняка будет вызвано на этапе проверки аргумента асинхронный вызов, который чаще всего является результатом того, что код моего приложения передает что-то, что не имеет никакого смысла, и я хочу узнать об этом, как только смогу. Кажется ли это разумным шаблоном для помощи в отладке обещаний, используемых в коде приложения в этом контексте?