Skip to content

Commit 5e2d2cf

Browse files
authored
fix(tracing): End http.client span on timeout (#3723)
If the http request times out, the http client span never gets finished. So make sure to finish it no matter what.
1 parent 5c5d98a commit 5e2d2cf

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

sentry_sdk/integrations/stdlib.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -127,11 +127,13 @@ def getresponse(self, *args, **kwargs):
127127
if span is None:
128128
return real_getresponse(self, *args, **kwargs)
129129

130-
rv = real_getresponse(self, *args, **kwargs)
130+
try:
131+
rv = real_getresponse(self, *args, **kwargs)
131132

132-
span.set_http_status(int(rv.status))
133-
span.set_data("reason", rv.reason)
134-
span.finish()
133+
span.set_http_status(int(rv.status))
134+
span.set_data("reason", rv.reason)
135+
finally:
136+
span.finish()
135137

136138
return rv
137139

tests/integrations/stdlib/test_httplib.py

+33
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import random
22
from http.client import HTTPConnection, HTTPSConnection
3+
from socket import SocketIO
34
from urllib.request import urlopen
45
from unittest import mock
56

@@ -342,3 +343,35 @@ def test_span_origin(sentry_init, capture_events):
342343

343344
assert event["spans"][0]["op"] == "http.client"
344345
assert event["spans"][0]["origin"] == "auto.http.stdlib.httplib"
346+
347+
348+
def test_http_timeout(monkeypatch, sentry_init, capture_envelopes):
349+
mock_readinto = mock.Mock(side_effect=TimeoutError)
350+
monkeypatch.setattr(SocketIO, "readinto", mock_readinto)
351+
352+
sentry_init(traces_sample_rate=1.0)
353+
354+
envelopes = capture_envelopes()
355+
356+
with start_transaction(op="op", name="name"):
357+
try:
358+
conn = HTTPSConnection("www.squirrelchasers.com")
359+
conn.request("GET", "/top-chasers")
360+
conn.getresponse()
361+
except Exception:
362+
pass
363+
364+
items = [
365+
item
366+
for envelope in envelopes
367+
for item in envelope.items
368+
if item.type == "transaction"
369+
]
370+
assert len(items) == 1
371+
372+
transaction = items[0].payload.json
373+
assert len(transaction["spans"]) == 1
374+
375+
span = transaction["spans"][0]
376+
assert span["op"] == "http.client"
377+
assert span["description"] == "GET https://www.squirrelchasers.com/top-chasers"

0 commit comments

Comments
 (0)