Skip to content

Support concurrent.future #2614

Open
Open
@wonkajin

Description

@wonkajin

Problem Statement

When using Sentry with ThreadPoolExecutor, I couldn't automatically capture errors like in this issue.

I think ThreadPoolExecutor use this run method.

    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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    FeaturePythonSDKTriagedHas been looked at recently during old issue triage

    Type

    No type

    Projects

    Status

    No status

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions