3

Twisted のDeferredクラスHeavyLifters Deferred Libraryを見た後、前の結果の値がFailureクラスのインスタンスである場合、エラーバックが発生することに気付きました。これにより、エラーをスローするのではなく、エラーを示す特別なオブジェクトを返す特定の理由があるのではないかと考えました。

私が推測したことから、次の理由により、エラーをスローする方が良いと感じています。

  1. 任意の値をスローできます。
  2. スローされた値がキャッチされない場合は、コール スタックを伝播します。
  3. 特別なクラスFailureErrorクラスは必要ありません。
  4. これにより、コールバックが同期コードのように見えます。
  5. 例外は、コール スタックの任意のレベルで処理できます。

私が気づいたいくつかの欠点は次のとおりです。

  1. コードのブロックを試行してエラーをキャッチすると、コードのパフォーマンスが低下する可能性があります。
  2. 例外がキャッチされない場合、残りのコールバック チェーンの実行が停止します。
  3. 非同期プログラミングは、try catch ブロックの使用とは正反対に不可欠です。

私はオッズを比較検討し、このシナリオでエラーを報告するのに適した方法を見つけようとしています。

4

2 に答える 2

1

Twistedのクラスには、エラー処理コールバックを実行Failureするための機能とは関係なく、便利なメソッドがいくつかあります。DeferredAPI ドキュメントを参照すると、トレースバックの書式設定や例外タイプのチェックなどに役立つメソッドが見つかります。 また、微妙に異なる例外を生成するCythonの特別なサポートコードのFailureジェネレーターとの統合を実現するための、いくつかの本当にひどいハックを置くのにも便利な場所です.twisted.internet.defer.inlineCallbacks

Failureまた、例外とともにトレースバックの状態を保持するのにも適しています。通常、Python の例外はスタック情報を持ちません。そのため、例外だけがある場合、例外が発生した場所を見つけることができません。exceptこれは、例外をキャッチしたブロックの外部で例外を処理する場合はいつでも、大きな欠点になる可能性があります。

最後に、 a を返すことができると、Failureこの単純で一般的に役立つパターンが有効になります。

def handleOneErrorCase(reason):
    if not thisCaseApplies(reason):
        return reason

    handleThisCase(reason)

someDeferred.addErrback(handleOneErrorCase)

これは、Deferred-using コードで頻繁に現れます。これは便利で、たまたま CPython でのパフォーマンスが向上し、元のスタック情報reasonが保持されるという利点もあります (例外がエラー ハンドラーによって再発生された場合、その時点のスタックは元のスタックを置き換えます。例外の元の原因を覆い隠します)。

于 2012-06-19T12:46:30.873 に答える
0

エラーは非同期関数の外部ではキャッチできないため、通常、非同期環境ではコールバックを使用してエラーが返されます。たとえば、JavaScriptで次のことを試してみてください。

try {
    setTimeout(function() { throw new Error(); }, 0);
} catch (e) {
    console.log('Caught it.');
}

その後、例外はキャッチされなくなります。これは、非同期関数が再登録され、後で別のスタックのイベントループによって呼び出されるため、例外によって元のスタックがバブルアップしないという事実と関係があります。

于 2012-06-19T05:49:52.973 に答える