getsentry / getsentry/sentry-python

Support concurrent.future

オープン
#2,614 コメント 4 件 リアクション 1 件 担当者 0 名 GitHub で見る
Errors Feature Python
主要言語
Python
スター
2.2k
フォーク
669
平均マージ
1日 1時間
マージ済み PR(30日)
213

説明

### Problem Statement

When using Sentry with ThreadPoolExecutor, I couldn't automatically capture errors like in this [issue](https://github.com/getsentry/sentry-python/issues/1234).

I think ThreadPoolExecutor use [this run method](https://github.com/python/cpython/blob/723f4d66982e4d2c54f8e874d6084ab7b2ff5833/Lib/concurrent/futures/thread.py#L53).
```
def run(self):
if not self.future.set_running_or_notify_cancel():
return
try:
result = self.fn(*self.args, **self.kwargs)
except BaseException as exc:
self.future.set_exception(exc)
# Break a reference cycle with the exception 'exc'
self = None
else:
self.future.set_result(result)
```

### Solution Brainstorm

In future.thread, it catches BaseException and handles it by using future.set_exception.
Therefore, I am planning to create FutureIntegration to patch Future.set_exception so that Sentry can handle it.

like this.

```
def setup_once():
from concurrent.futures import Future
from concurrent.futures._base import CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED, InvalidStateError

def sentry_set_exception(self, exception):
with self._condition:
if self._state in {CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED}:
raise InvalidStateError('{}: {!r}'.format(self._state, self))
self._exception = exception
self._state = FINISHED
for waiter in self._waiters:
waiter.add_exception(self)
self._condition.notify_all()
self._invoke_callbacks()

_capture_exception()

Future.set_exception = sentry_set_exception
```

I've tested this process in my local environment and confirmed that it works well. Would it be okay for me to contribute in this way?

コントリビューションガイド

コントリビューションガイドを開く

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。