私は Ember.js 内で配布されている RSVP ライブラリを使用しており、promise 内で致命的なエラーを報告するための正しいパターンを見つけようとしています。 APIの誤用と私はLOUDの方法でそれをしたい. 私はプロミスと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)
これが行っていることは、非同期関数呼び出しの呼び出し自体が例外を発生させるたびに、どこかから強制的に例外をスローすることだと思い ます-そのような例外は、非同期呼び出しの引数検証フェーズで発生することが最も一般的です。私のアプリケーションコードが意味をなさないものを渡した結果になるでしょう - そして私はできるだけ早くそれについて知りたいと思っています. これは、このコンテキストでアプリケーション コードで使用される promise のデバッグを支援するために従うべき合理的なパターンのように思えますか?