9

ツイストリアクターが実行中で、キャッチされない遅延内で例外が発生すると、「未処理エラー」がトレースバックと例外とともに端末に出力されます。これらの例外を処理/インターセプトすることは可能ですか(たとえば、コールバックを設定するか、メソッドをオーバーライドします)?

編集:deferrerdにerrbackを追加することで、失敗をキャッチできることを認識しています。私が知りたいのは、チェーンを上って原子炉に到達した未処理の障害/例外をインターセプトする方法があるかどうかです。

編集:基本的に、ツイストリアクターにグローバルエラーハンドラーまたはアクセス可能なものがあるかどうか疑問に思っています。失敗からのトレースバックとエラーを出力するので疑問に思います。

例:

Unhandled Error
Traceback (most recent call last):
  File "/var/projects/python/server.py", line 359, in run_server
    return server.run()
  File "/var/projects/python/server.py", line 881, in run
    reactor.run()
  File "/usr/local/lib/python2.6/dist-packages/Twisted-11.0.0-py2.6-linux-x86_64.egg/twisted/internet/base.py", line 1162, in run
    self.mainLoop()
  File "/usr/local/lib/python2.6/dist-packages/Twisted-11.0.0-py2.6-linux-x86_64.egg/twisted/internet/base.py", line 1171, in mainLoop
    self.runUntilCurrent()
--- <exception caught here> ---
  File "/usr/local/lib/python2.6/dist-packages/Twisted-11.0.0-py2.6-linux-x86_64.egg/twisted/internet/base.py", line 793, in runUntilCurrent
    call.func(*call.args, **call.kw)
  File "/var/projects/python/server.py", line 524, in monitor
    elapsed = time.time() - info.last
exceptions.NameError: global name 'info' is not defined
4

3 に答える 3

6

これらのトレースバックはtwisted.python.log.deferr()(とにかくTwisted 10.2で)への呼び出しを使用して書き込まれるため、ログオブザーバーを使用してリダイレクトすることができます。これは、これらのスタックトレースで行う最も一般的なことです。(驚くべきことに)ログオブザーバーの基本クラスは見つかりませんが、いくつかの組み込みクラスがあります。

twisted.python.log.PythonLoggingObserver-ログに記録されたものはすべて、標準のPythonloggingモジュールに送られます。(これをアプリケーションで使用します。)

twisted.python.log.FileLogObserver-ログに記録されたものはすべてファイルに送られます。

これらは両方とも、リアクターによって報告されたスタックトレースをキャッチします。ログオブザーバー(引数なし)を作成してから、オブジェクトのstart()メソッドを呼び出すだけです。

(補足:StdioOnnaStick作成して割り当てることができるクラスもあります。sys.stdout必要sys.stderrに応じprintて、ツイストログに移動します。)

実際には、これらの呼び出しを本当にインターセプトして、スタックトレースがまったくログに記録されないようにするには、次のいずれかを実行できます。

  • そのメソッドをサブクラスtwisted.internet.SelectReactor化してオーバーライドしますrunUntilCurrent()。これがスタックトレースをログに記録するものです。twisted.internet.base.ReactorBaseこれを行う前に、のソースを調査する必要があります。
  • すべてのtwisted.*インポートを完了したらtwisted.python.log.deferr、プロトタイプと互換性のある、選択した関数に設定しますdef err(_stuff=None, _why=None, **kw)
于 2011-08-05T22:08:30.910 に答える
3

遅延にエラーバックを追加できます。未処理の例外は自動的にに変換されtwisted.python.failure.Failureます。

于 2011-08-05T21:19:14.307 に答える
1

あなたのコメントに答える:

基本的に、ツイストリアクターにグローバルエラーハンドラーまたはアクセス可能なものがあるかどうか疑問に思っています。失敗からのトレースバックとエラーを出力するので疑問に思います。

応答は「適切な方法ではありません」です。

まず、reactorは遅延とは何の関係もありません。実際には、遅延モジュール全体をtwisted.pythonパッケージに配置する必要がありますが、依存関係があるため、これはまだ実行できません。質問に戻ります...

ツイストコード(より正確にはtwisted.internet.deferモジュール)を掘り下げると、次のイベントフローの概要を説明できます。

  1. メソッドが結果とともに呼び出されると、callback遅延インスタンスは_runCallbacksメソッドを介してコールバックの実行を開始します。
  2. コールバックの1つが例外をスローした場合、それは失敗にラップされます(542行目)。
  3. コールバックチェーンが使い果たされ、最後の結果が失敗した場合、現在の結果がDebugInfoインスタンスのfailResultプロパティに割り当てられます(575行目)。
  4. 遅延インスタンス、つまりそのDebugInfoインスタンスがガベージコレクションされ、結果としてアクティブな障害がまだ存在する場合、DebugInfo.__del__メソッドが呼び出され、トレースバックが出力されます。

これらの前提を考えると、最も簡単な解決策の1つは、DebugInfoクラスにモンキーパッチを適用することです。

from twisted.internet.defer import DebugInfo
del DebugInfo.__del__  # Hides all errors
于 2011-08-05T22:12:19.203 に答える