@Denisと@lvoが言っているように、link_exception
はOKですが、私は緑の子を生み出すためにあなたの現在のコードを変更することなく、もっと良い方法があると思います。
一般的に、グリーンレットに例外がスローされると、そのグリーンレットに対して_report_error
メソッド(gevent.greenlet.Greenlet
)が呼び出されます。それはすべてのリンク関数を呼び出すようないくつかのものを行い、最終的に現在のスタックからexc_infoでself.parent.handle_error
を呼び出します。ここでself.parent
はグローバルHub
オブジェクトです。つまり、各グリーンレットで発生したすべての例外は、常に1つの処理方法に集中します。デフォルトではHub.handle_error
は例外タイプを区別し、いくつかのタイプを無視して他のものを表示します(これは私たちがコンソールで見たものです)。
Hub.handle_error
メソッドにパッチを適用することで、私たち自身のエラーハンドラを簡単に登録して、もはやエラーを失うことはありません。私はそれを実現するためにヘルパー関数を書きました:
from gevent.hub import Hub
IGNORE_ERROR = Hub.SYSTEM_ERROR + Hub.NOT_ERROR
def register_error_handler(error_handler):
Hub._origin_handle_error = Hub.handle_error
def custom_handle_error(self, context, type, value, tb):
if not issubclass(type, IGNORE_ERROR):
# print 'Got error from greenlet:', context, type, value, tb
error_handler(context, (type, value, tb))
self._origin_handle_error(context, type, value, tb)
Hub.handle_error = custom_handle_error
これを使用するには、イベントループが初期化される前に、ちょうどそれを呼び出す:
def gevent_error_handler(context, exc_info):
"""Here goes your custom error handling logics"""
e = exc_info[1]
if isinstance(e, SomeError):
# do some notify things
pass
sentry_client.captureException(exc_info=exc_info)
register_error_handler(gevent_error_handler)
をこのソリューションはgevent 1.0.2と1.1の下でテストされていますb3、我々はセンチリー(例外追跡システム)にグリーンレットのエラー情報を送信するためにそれを使用していますが、これまでのところうまくいきます。
ミッションクリティカルなグリーンレットを非常に小さくしました(コード8行)。 – Stephan