我正在使用分布在 Ember.js 中的 RSVP 库,我正在尝试找出在承诺中报告致命错误的正确模式——特别是我想告知一些几乎可以肯定是由于编程错误导致的结果api 滥用,我想以大声的方式来做。一般来说,我是 Promise 和 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 返回之前将这样的默认错误处理程序附加到promise 是否被认为是一种合理的做法?这将允许我在调用者执行一些不可能的操作时强制执行堆栈跟踪——即使堆栈跟踪会有点奇怪,它可以让事情更容易开始......
尽管我将示例承诺返回函数称为“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)
我认为这样做是在 我的异步函数调用本身引发异常的任何时候强制从某个地方抛出异常——这样的异常几乎肯定会在异步调用的参数验证阶段引发,这是最常见的这将是我的应用程序代码传入一些没有任何意义的东西的结果——我想尽快找出答案。在这种情况下,这似乎是一种有助于调试应用程序代码中使用的承诺的合理模式吗?