Skip to content

Commit

Permalink
fix(tracing): End http.client span on timeout (#3723)
Browse files Browse the repository at this point in the history
If the http request times out, the http client span never gets finished. So make
sure to finish it no matter what.
  • Loading branch information
Zylphrex authored Oct 31, 2024
1 parent 5c5d98a commit 5e2d2cf
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 4 deletions.
10 changes: 6 additions & 4 deletions sentry_sdk/integrations/stdlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,11 +127,13 @@ def getresponse(self, *args, **kwargs):
if span is None:
return real_getresponse(self, *args, **kwargs)

rv = real_getresponse(self, *args, **kwargs)
try:
rv = real_getresponse(self, *args, **kwargs)

span.set_http_status(int(rv.status))
span.set_data("reason", rv.reason)
span.finish()
span.set_http_status(int(rv.status))
span.set_data("reason", rv.reason)
finally:
span.finish()

return rv

Expand Down
33 changes: 33 additions & 0 deletions tests/integrations/stdlib/test_httplib.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import random
from http.client import HTTPConnection, HTTPSConnection
from socket import SocketIO
from urllib.request import urlopen
from unittest import mock

Expand Down Expand Up @@ -342,3 +343,35 @@ def test_span_origin(sentry_init, capture_events):

assert event["spans"][0]["op"] == "http.client"
assert event["spans"][0]["origin"] == "auto.http.stdlib.httplib"


def test_http_timeout(monkeypatch, sentry_init, capture_envelopes):
mock_readinto = mock.Mock(side_effect=TimeoutError)
monkeypatch.setattr(SocketIO, "readinto", mock_readinto)

sentry_init(traces_sample_rate=1.0)

envelopes = capture_envelopes()

with start_transaction(op="op", name="name"):
try:
conn = HTTPSConnection("www.squirrelchasers.com")
conn.request("GET", "/top-chasers")
conn.getresponse()
except Exception:
pass

items = [
item
for envelope in envelopes
for item in envelope.items
if item.type == "transaction"
]
assert len(items) == 1

transaction = items[0].payload.json
assert len(transaction["spans"]) == 1

span = transaction["spans"][0]
assert span["op"] == "http.client"
assert span["description"] == "GET https://www.squirrelchasers.com/top-chasers"

0 comments on commit 5e2d2cf

Please sign in to comment.