Skip to content

Commit 50553d4

Browse files
committed
feat(asyncio): Add patching for loop.close in asyncio
GH-4601
1 parent ed392e9 commit 50553d4

File tree

1 file changed

+45
-0
lines changed

1 file changed

+45
-0
lines changed

sentry_sdk/integrations/asyncio.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from sentry_sdk.consts import OP
66
from sentry_sdk.integrations import Integration, DidNotEnable
77
from sentry_sdk.utils import event_from_exception, logger, reraise
8+
from sentry_sdk.transport import AsyncHttpTransport
89

910
try:
1011
import asyncio
@@ -124,3 +125,47 @@ class AsyncioIntegration(Integration):
124125
@staticmethod
125126
def setup_once() -> None:
126127
patch_asyncio()
128+
129+
def _patch_loop_close() -> None:
130+
# Atexit shutdown hook happens after the event loop is closed.
131+
# Therefore, it is necessary to patch the loop.close method to ensure
132+
# that pending events are flushed before the interpreter shuts down.
133+
try:
134+
loop = asyncio.get_running_loop()
135+
except RuntimeError:
136+
# No running loop → cannot patch now
137+
return
138+
139+
if getattr(loop, "_sentry_flush_patched", False):
140+
return
141+
142+
async def _flush() -> None:
143+
client = sentry_sdk.get_client()
144+
if not client:
145+
return
146+
try:
147+
148+
if not isinstance(client.transport, AsyncHttpTransport):
149+
return
150+
151+
t = client.close()
152+
if t is not None:
153+
# Wait for the task to complete.
154+
await t # type: ignore
155+
except Exception:
156+
logger.warning(
157+
"Sentry flush failed during loop shutdown", exc_info=True
158+
)
159+
160+
orig_close = loop.close
161+
162+
def _patched_close() -> None:
163+
try:
164+
loop.run_until_complete(_flush())
165+
finally:
166+
orig_close()
167+
168+
loop.close = _patched_close
169+
loop._sentry_flush_patched = True # type: ignore
170+
171+
_patch_loop_close()

0 commit comments

Comments
 (0)