We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Support upcoming version of RQ
### Problem Statement

I'm [RQ](https://github.com/rq/rq)'s maintainer and I use Sentry in production. I plan on releasing a major improvement to RQ sometime in the next few weeks, but this upcoming change breaks Sentry's integration.


### Solution Brainstorm

This [pull request](https://github.com/rq/rq/pull/1964) introduces a change that causes Sentry's RQ integration to fail. From what I can tell, the failure is caused by [this change](https://github.com/rq/rq/pull/1964/commits/fadbb233d81c5c1a53bfcae7149b80888c1e7bdd).

Can we get Sentry to support this change prior to the next major release of RQ? I plan on releasing this sometime in the next few weeks.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sentry_sdk/integrations/rq.py`
Content:
```
1 from __future__ import absolute_import
2 
3 import weakref
4 from sentry_sdk.consts import OP
5 
6 from sentry_sdk.api import continue_trace
7 from sentry_sdk.hub import Hub
8 from sentry_sdk.integrations import DidNotEnable, Integration
9 from sentry_sdk.integrations.logging import ignore_logger
10 from sentry_sdk.tracing import TRANSACTION_SOURCE_TASK
11 from sentry_sdk.utils import (
12     capture_internal_exceptions,
13     event_from_exception,
14     format_timestamp,
15     parse_version,
16 )
17 
18 try:
19     from rq.queue import Queue
20     from rq.timeouts import JobTimeoutException
21     from rq.version import VERSION as RQ_VERSION
22     from rq.worker import Worker
23 except ImportError:
24     raise DidNotEnable("RQ not installed")
25 
26 from sentry_sdk._types import TYPE_CHECKING
27 
28 if TYPE_CHECKING:
29     from typing import Any, Callable, Dict
30 
31     from sentry_sdk._types import EventProcessor
32     from sentry_sdk.utils import ExcInfo
33 
34     from rq.job import Job
35 
36 
37 class RqIntegration(Integration):
38     identifier = "rq"
39 
40     @staticmethod
41     def setup_once():
42         # type: () -> None
43 
44         version = parse_version(RQ_VERSION)
45 
46         if version is None:
47             raise DidNotEnable("Unparsable RQ version: {}".format(RQ_VERSION))
48 
49         if version < (0, 6):
50             raise DidNotEnable("RQ 0.6 or newer is required.")
51 
52         old_perform_job = Worker.perform_job
53 
54         def sentry_patched_perform_job(self, job, *args, **kwargs):
55             # type: (Any, Job, *Queue, **Any) -> bool
56             hub = Hub.current
57             integration = hub.get_integration(RqIntegration)
58 
59             if integration is None:
60                 return old_perform_job(self, job, *args, **kwargs)
61 
62             client = hub.client
63             assert client is not None
64 
65             with hub.push_scope() as scope:
66                 scope.clear_breadcrumbs()
67                 scope.add_event_processor(_make_event_processor(weakref.ref(job)))
68 
69                 transaction = continue_trace(
70                     job.meta.get("_sentry_trace_headers") or {},
71                     op=OP.QUEUE_TASK_RQ,
72                     name="unknown RQ task",
73                     source=TRANSACTION_SOURCE_TASK,
74                 )
75 
76                 with capture_internal_exceptions():
77                     transaction.name = job.func_name
78 
79                 with hub.start_transaction(
80                     transaction, custom_sampling_context={"rq_job": job}
81                 ):
82                     rv = old_perform_job(self, job, *args, **kwargs)
83 
84             if self.is_horse:
85                 # We're inside of a forked process and RQ is
86                 # about to call `os._exit`. Make sure that our
87                 # events get sent out.
88                 client.flush()
89 
90             return rv
91 
92         Worker.perform_job = sentry_patched_perform_job
93 
94         old_handle_exception = Worker.handle_exception
95 
96         def sentry_patched_handle_exception(self, job, *exc_info, **kwargs):
97             # type: (Worker, Any, *Any, **Any) -> Any
98             if job.is_failed:
99                 _capture_exception(exc_info)  # type: ignore
100 
101             return old_handle_exception(self, job, *exc_info, **kwargs)
102 
103         Worker.handle_exception = sentry_patched_handle_exception
104 
105         old_enqueue_job = Queue.enqueue_job
106 
107         def sentry_patched_enqueue_job(self, job, **kwargs):
108             # type: (Queue, Any, **Any) -> Any
109             hub = Hub.current
110             if hub.get_integration(RqIntegration) is not None:
111                 if hub.scope.span is not None:
112                     job.meta["_sentry_trace_headers"] = dict(
113                         hub.iter_trace_propagation_headers()
114                     )
115 
116             return old_enqueue_job(self, job, **kwargs)
117 
118         Queue.enqueue_job = sentry_patched_enqueue_job
119 
120         ignore_logger("rq.worker")
121 
122 
123 def _make_event_processor(weak_job):
124     # type: (Callable[[], Job]) -> EventProcessor
125     def event_processor(event, hint):
126         # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]
127         job = weak_job()
128         if job is not None:
129             with capture_internal_exceptions():
130                 extra = event.setdefault("extra", {})
131                 extra["rq-job"] = {
132                     "job_id": job.id,
133                     "func": job.func_name,
134                     "args": job.args,
135                     "kwargs": job.kwargs,
136                     "description": job.description,
137                 }
138 
139                 if job.enqueued_at:
140                     extra["rq-job"]["enqueued_at"] = format_timestamp(job.enqueued_at)
141                 if job.started_at:
142                     extra["rq-job"]["started_at"] = format_timestamp(job.started_at)
143 
144         if "exc_info" in hint:
145             with capture_internal_exceptions():
146                 if issubclass(hint["exc_info"][0], JobTimeoutException):
147                     event["fingerprint"] = ["rq", "JobTimeoutException", job.func_name]
148 
149         return event
150 
151     return event_processor
152 
153 
154 def _capture_exception(exc_info, **kwargs):
155     # type: (ExcInfo, **Any) -> None
156     hub = Hub.current
157     if hub.get_integration(RqIntegration) is None:
158         return
159 
160     # If an integration is there, a client has to be there.
161     client = hub.client  # type: Any
162 
163     event, hint = event_from_exception(
164         exc_info,
165         client_options=client.options,
166         mechanism={"type": "rq", "handled": False},
167     )
168 
169     hub.capture_event(event, hint=hint)
170
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sentry_sdk/integrations/rq.py b/sentry_sdk/integrations/rq.py
--- a/sentry_sdk/integrations/rq.py
+++ b/sentry_sdk/integrations/rq.py
@@ -20,6 +20,7 @@
     from rq.timeouts import JobTimeoutException
     from rq.version import VERSION as RQ_VERSION
     from rq.worker import Worker
+    from rq.job import JobStatus
 except ImportError:
     raise DidNotEnable("RQ not installed")
 
@@ -95,7 +96,9 @@
 
         def sentry_patched_handle_exception(self, job, *exc_info, **kwargs):
             # type: (Worker, Any, *Any, **Any) -> Any
-            if job.is_failed:
+            # Note, the order of the `or` here is important,
+            # because calling `job.is_failed` will change `_status`.
+            if job._status == JobStatus.FAILED or job.is_failed:
                 _capture_exception(exc_info)  # type: ignore
 
             return old_handle_exception(self, job, *exc_info, **kwargs)

{"golden_diff": "diff --git a/sentry_sdk/integrations/rq.py b/sentry_sdk/integrations/rq.py\n--- a/sentry_sdk/integrations/rq.py\n+++ b/sentry_sdk/integrations/rq.py\n@@ -20,6 +20,7 @@\n     from rq.timeouts import JobTimeoutException\n     from rq.version import VERSION as RQ_VERSION\n     from rq.worker import Worker\n+    from rq.job import JobStatus\n except ImportError:\n     raise DidNotEnable(\"RQ not installed\")\n \n@@ -95,7 +96,9 @@\n \n         def sentry_patched_handle_exception(self, job, *exc_info, **kwargs):\n             # type: (Worker, Any, *Any, **Any) -> Any\n-            if job.is_failed:\n+            # Note, the order of the `or` here is important,\n+            # because calling `job.is_failed` will change `_status`.\n+            if job._status == JobStatus.FAILED or job.is_failed:\n                 _capture_exception(exc_info)  # type: ignore\n \n             return old_handle_exception(self, job, *exc_info, **kwargs)\n", "issue": "Support upcoming version of RQ\n### Problem Statement\n\nI'm [RQ](https://github.com/rq/rq)'s maintainer and I use Sentry in production. I plan on releasing a major improvement to RQ sometime in the next few weeks, but this upcoming change breaks Sentry's integration.\r\n\n\n### Solution Brainstorm\n\nThis [pull request](https://github.com/rq/rq/pull/1964) introduces a change that causes Sentry's RQ integration to fail. From what I can tell, the failure is caused by [this change](https://github.com/rq/rq/pull/1964/commits/fadbb233d81c5c1a53bfcae7149b80888c1e7bdd).\r\n\r\nCan we get Sentry to support this change prior to the next major release of RQ? I plan on releasing this sometime in the next few weeks.\r\n\n", "before_files": [{"content": "from __future__ import absolute_import\n\nimport weakref\nfrom sentry_sdk.consts import OP\n\nfrom sentry_sdk.api import continue_trace\nfrom sentry_sdk.hub import Hub\nfrom sentry_sdk.integrations import DidNotEnable, Integration\nfrom sentry_sdk.integrations.logging import ignore_logger\nfrom sentry_sdk.tracing import TRANSACTION_SOURCE_TASK\nfrom sentry_sdk.utils import (\n    capture_internal_exceptions,\n    event_from_exception,\n    format_timestamp,\n    parse_version,\n)\n\ntry:\n    from rq.queue import Queue\n    from rq.timeouts import JobTimeoutException\n    from rq.version import VERSION as RQ_VERSION\n    from rq.worker import Worker\nexcept ImportError:\n    raise DidNotEnable(\"RQ not installed\")\n\nfrom sentry_sdk._types import TYPE_CHECKING\n\nif TYPE_CHECKING:\n    from typing import Any, Callable, Dict\n\n    from sentry_sdk._types import EventProcessor\n    from sentry_sdk.utils import ExcInfo\n\n    from rq.job import Job\n\n\nclass RqIntegration(Integration):\n    identifier = \"rq\"\n\n    @staticmethod\n    def setup_once():\n        # type: () -> None\n\n        version = parse_version(RQ_VERSION)\n\n        if version is None:\n            raise DidNotEnable(\"Unparsable RQ version: {}\".format(RQ_VERSION))\n\n        if version < (0, 6):\n            raise DidNotEnable(\"RQ 0.6 or newer is required.\")\n\n        old_perform_job = Worker.perform_job\n\n        def sentry_patched_perform_job(self, job, *args, **kwargs):\n            # type: (Any, Job, *Queue, **Any) -> bool\n            hub = Hub.current\n            integration = hub.get_integration(RqIntegration)\n\n            if integration is None:\n                return old_perform_job(self, job, *args, **kwargs)\n\n            client = hub.client\n            assert client is not None\n\n            with hub.push_scope() as scope:\n                scope.clear_breadcrumbs()\n                scope.add_event_processor(_make_event_processor(weakref.ref(job)))\n\n                transaction = continue_trace(\n                    job.meta.get(\"_sentry_trace_headers\") or {},\n                    op=OP.QUEUE_TASK_RQ,\n                    name=\"unknown RQ task\",\n                    source=TRANSACTION_SOURCE_TASK,\n                )\n\n                with capture_internal_exceptions():\n                    transaction.name = job.func_name\n\n                with hub.start_transaction(\n                    transaction, custom_sampling_context={\"rq_job\": job}\n                ):\n                    rv = old_perform_job(self, job, *args, **kwargs)\n\n            if self.is_horse:\n                # We're inside of a forked process and RQ is\n                # about to call `os._exit`. Make sure that our\n                # events get sent out.\n                client.flush()\n\n            return rv\n\n        Worker.perform_job = sentry_patched_perform_job\n\n        old_handle_exception = Worker.handle_exception\n\n        def sentry_patched_handle_exception(self, job, *exc_info, **kwargs):\n            # type: (Worker, Any, *Any, **Any) -> Any\n            if job.is_failed:\n                _capture_exception(exc_info)  # type: ignore\n\n            return old_handle_exception(self, job, *exc_info, **kwargs)\n\n        Worker.handle_exception = sentry_patched_handle_exception\n\n        old_enqueue_job = Queue.enqueue_job\n\n        def sentry_patched_enqueue_job(self, job, **kwargs):\n            # type: (Queue, Any, **Any) -> Any\n            hub = Hub.current\n            if hub.get_integration(RqIntegration) is not None:\n                if hub.scope.span is not None:\n                    job.meta[\"_sentry_trace_headers\"] = dict(\n                        hub.iter_trace_propagation_headers()\n                    )\n\n            return old_enqueue_job(self, job, **kwargs)\n\n        Queue.enqueue_job = sentry_patched_enqueue_job\n\n        ignore_logger(\"rq.worker\")\n\n\ndef _make_event_processor(weak_job):\n    # type: (Callable[[], Job]) -> EventProcessor\n    def event_processor(event, hint):\n        # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]\n        job = weak_job()\n        if job is not None:\n            with capture_internal_exceptions():\n                extra = event.setdefault(\"extra\", {})\n                extra[\"rq-job\"] = {\n                    \"job_id\": job.id,\n                    \"func\": job.func_name,\n                    \"args\": job.args,\n                    \"kwargs\": job.kwargs,\n                    \"description\": job.description,\n                }\n\n                if job.enqueued_at:\n                    extra[\"rq-job\"][\"enqueued_at\"] = format_timestamp(job.enqueued_at)\n                if job.started_at:\n                    extra[\"rq-job\"][\"started_at\"] = format_timestamp(job.started_at)\n\n        if \"exc_info\" in hint:\n            with capture_internal_exceptions():\n                if issubclass(hint[\"exc_info\"][0], JobTimeoutException):\n                    event[\"fingerprint\"] = [\"rq\", \"JobTimeoutException\", job.func_name]\n\n        return event\n\n    return event_processor\n\n\ndef _capture_exception(exc_info, **kwargs):\n    # type: (ExcInfo, **Any) -> None\n    hub = Hub.current\n    if hub.get_integration(RqIntegration) is None:\n        return\n\n    # If an integration is there, a client has to be there.\n    client = hub.client  # type: Any\n\n    event, hint = event_from_exception(\n        exc_info,\n        client_options=client.options,\n        mechanism={\"type\": \"rq\", \"handled\": False},\n    )\n\n    hub.capture_event(event, hint=hint)\n", "path": "sentry_sdk/integrations/rq.py"}], "after_files": [{"content": "from __future__ import absolute_import\n\nimport weakref\nfrom sentry_sdk.consts import OP\n\nfrom sentry_sdk.api import continue_trace\nfrom sentry_sdk.hub import Hub\nfrom sentry_sdk.integrations import DidNotEnable, Integration\nfrom sentry_sdk.integrations.logging import ignore_logger\nfrom sentry_sdk.tracing import TRANSACTION_SOURCE_TASK\nfrom sentry_sdk.utils import (\n    capture_internal_exceptions,\n    event_from_exception,\n    format_timestamp,\n    parse_version,\n)\n\ntry:\n    from rq.queue import Queue\n    from rq.timeouts import JobTimeoutException\n    from rq.version import VERSION as RQ_VERSION\n    from rq.worker import Worker\n    from rq.job import JobStatus\nexcept ImportError:\n    raise DidNotEnable(\"RQ not installed\")\n\nfrom sentry_sdk._types import TYPE_CHECKING\n\nif TYPE_CHECKING:\n    from typing import Any, Callable, Dict\n\n    from sentry_sdk._types import EventProcessor\n    from sentry_sdk.utils import ExcInfo\n\n    from rq.job import Job\n\n\nclass RqIntegration(Integration):\n    identifier = \"rq\"\n\n    @staticmethod\n    def setup_once():\n        # type: () -> None\n\n        version = parse_version(RQ_VERSION)\n\n        if version is None:\n            raise DidNotEnable(\"Unparsable RQ version: {}\".format(RQ_VERSION))\n\n        if version < (0, 6):\n            raise DidNotEnable(\"RQ 0.6 or newer is required.\")\n\n        old_perform_job = Worker.perform_job\n\n        def sentry_patched_perform_job(self, job, *args, **kwargs):\n            # type: (Any, Job, *Queue, **Any) -> bool\n            hub = Hub.current\n            integration = hub.get_integration(RqIntegration)\n\n            if integration is None:\n                return old_perform_job(self, job, *args, **kwargs)\n\n            client = hub.client\n            assert client is not None\n\n            with hub.push_scope() as scope:\n                scope.clear_breadcrumbs()\n                scope.add_event_processor(_make_event_processor(weakref.ref(job)))\n\n                transaction = continue_trace(\n                    job.meta.get(\"_sentry_trace_headers\") or {},\n                    op=OP.QUEUE_TASK_RQ,\n                    name=\"unknown RQ task\",\n                    source=TRANSACTION_SOURCE_TASK,\n                )\n\n                with capture_internal_exceptions():\n                    transaction.name = job.func_name\n\n                with hub.start_transaction(\n                    transaction, custom_sampling_context={\"rq_job\": job}\n                ):\n                    rv = old_perform_job(self, job, *args, **kwargs)\n\n            if self.is_horse:\n                # We're inside of a forked process and RQ is\n                # about to call `os._exit`. Make sure that our\n                # events get sent out.\n                client.flush()\n\n            return rv\n\n        Worker.perform_job = sentry_patched_perform_job\n\n        old_handle_exception = Worker.handle_exception\n\n        def sentry_patched_handle_exception(self, job, *exc_info, **kwargs):\n            # type: (Worker, Any, *Any, **Any) -> Any\n            # Note, the order of the `or` here is important,\n            # because calling `job.is_failed` will change `_status`.\n            if job._status == JobStatus.FAILED or job.is_failed:\n                _capture_exception(exc_info)  # type: ignore\n\n            return old_handle_exception(self, job, *exc_info, **kwargs)\n\n        Worker.handle_exception = sentry_patched_handle_exception\n\n        old_enqueue_job = Queue.enqueue_job\n\n        def sentry_patched_enqueue_job(self, job, **kwargs):\n            # type: (Queue, Any, **Any) -> Any\n            hub = Hub.current\n            if hub.get_integration(RqIntegration) is not None:\n                if hub.scope.span is not None:\n                    job.meta[\"_sentry_trace_headers\"] = dict(\n                        hub.iter_trace_propagation_headers()\n                    )\n\n            return old_enqueue_job(self, job, **kwargs)\n\n        Queue.enqueue_job = sentry_patched_enqueue_job\n\n        ignore_logger(\"rq.worker\")\n\n\ndef _make_event_processor(weak_job):\n    # type: (Callable[[], Job]) -> EventProcessor\n    def event_processor(event, hint):\n        # type: (Dict[str, Any], Dict[str, Any]) -> Dict[str, Any]\n        job = weak_job()\n        if job is not None:\n            with capture_internal_exceptions():\n                extra = event.setdefault(\"extra\", {})\n                extra[\"rq-job\"] = {\n                    \"job_id\": job.id,\n                    \"func\": job.func_name,\n                    \"args\": job.args,\n                    \"kwargs\": job.kwargs,\n                    \"description\": job.description,\n                }\n\n                if job.enqueued_at:\n                    extra[\"rq-job\"][\"enqueued_at\"] = format_timestamp(job.enqueued_at)\n                if job.started_at:\n                    extra[\"rq-job\"][\"started_at\"] = format_timestamp(job.started_at)\n\n        if \"exc_info\" in hint:\n            with capture_internal_exceptions():\n                if issubclass(hint[\"exc_info\"][0], JobTimeoutException):\n                    event[\"fingerprint\"] = [\"rq\", \"JobTimeoutException\", job.func_name]\n\n        return event\n\n    return event_processor\n\n\ndef _capture_exception(exc_info, **kwargs):\n    # type: (ExcInfo, **Any) -> None\n    hub = Hub.current\n    if hub.get_integration(RqIntegration) is None:\n        return\n\n    # If an integration is there, a client has to be there.\n    client = hub.client  # type: Any\n\n    event, hint = event_from_exception(\n        exc_info,\n        client_options=client.options,\n        mechanism={\"type\": \"rq\", \"handled\": False},\n    )\n\n    hub.capture_event(event, hint=hint)\n", "path": "sentry_sdk/integrations/rq.py"}]}