“LOUD”错误的可接受承诺模式? [英] acceptable promise pattern for 'LOUD' errors?
问题描述
这是一个简单的例子(在咖啡书中):
doAsync =(arg,callback) - >
抛出新的错误('你给我一个方法不好的参数,我失败了!'
promiseReturningApi =(data) - >
返回新的Ember.RSVP.Promise(resolve,reject) - >
callback =(err,resp) - >
如果err然后拒绝(err)
else resolve(resp)
doAsync(data,callback)
现在可以说我已经发现一个错误,没有可能的方法来恢复在哪里发生在doAsync内 - 我想确保这个错误被报告,即使调用者忽略附加一个错误处理程序,因为它几乎肯定只是因为调用者以不正确的方式调用api函数
我遇到了在拒绝处理程序中使用setTimeout的想法,以确保错误得到即使呼叫者没有在承诺中附加错误处理程序
failLoud = (err) - >
如果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) - >
如果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)
我认为在异步函数调用调用本身引发异常的时候,这样做正在强制从某处抛出一个异常 - 在异步的参数验证阶段几乎肯定会引发这种异常调用最常见的方式是将我的应用程序代码传递给一些没有任何意义的结果,而且我想尽可能快地了解一下。这样做似乎是一个合理的模式来帮助调试在这个上下文中应用代码中使用的承诺?
新的答案 - -
在这个与ember核心开发人员的视频小组讨论中,开发人员有一个共同的调试提示:
http://www.youtube.com/watch?v=L9OOMygo1HI
Tom Dale专门解决了承诺中吞咽异常的问题,并建议使用新的Ember.RSVP.onerror功能来调试承诺中的错误,否则将不会报告,因为没有拒绝处理程序被附加。
我认为这是我问题的正确答案 - 虽然我还不知道如何使用RSVP.onerror回调(或其中ember释放它可用)...
I'm using the RSVP library distributed inside Ember.js and I'm trying to figure out the correct pattern for reporting fatal errors inside a promise -- particularly I want to inform of something that's almost certainly the result of a programming error due to api misuse and I want to do it in a LOUD way. I'm new to promises and javascript in general, hopefully this question makes sense
Here's a simple example (in 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)
Now lets say I've identified an error that there's no possible way to recover from which occurred inside doAsync -- I want to make sure this error gets reported even if the caller neglected to attach an error handler because it almost certainly only resulted because the caller invoked the api function in an incorrect way
I came across the idea of using setTimeout within a rejection handler to ensure the error gets raised from somewhere even if the caller doesn't attach an error handler to the promise
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)
Is it considered a reasonable practice to attach such a default error handler to a promise before returning it from my promiseReturningApi? This would allow me to force a stacktrace when the caller does something that can't possibly work -- even though the stacktrace would be a little odd it could make things a bit easier to get started with ...
Even though I called the example promise returning function an 'api' call -- I should add that I'm not writing framework code -- this is rather all within an application. If doAsync were a real-world function, then in my versio of the real-world its pretty likely to be coming from an external party with a new-to-me api -- so it seems pretty likely that I'll misuse it while I'm getting to know it... Meaning I might want to make the pattern something like this
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)
I think what this is doing is forcing an exception to be thrown from somewhere any time that my asynchronous function call invocation itself raises an exception -- such an exception would almost certainly be raised during the argument validation phase of the async call which is most commonly going to be the result of my application code passing in something which doesn't make any sense -- and I want to find out about that as soon as I can. Does this seem like a reasonable pattern to follow to aid in debugging promises used in application code in this context?
New answer --
In this video panel discussion with ember core developers, at one point the developers all share one debugging tip:
http://www.youtube.com/watch?v=L9OOMygo1HI
Tom Dale specifically addresses the issue of swallowed exceptions inside promises and recommends use of the new Ember.RSVP.onerror feature for debugging errors inside promises which would have otherwise gone unreported because no rejection handler was attached.
I think that is the correct answer to my question -- although I don't yet know how to use the RSVP.onerror callback (or in which ember releases its available) ...
这篇关于“LOUD”错误的可接受承诺模式?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!