Skip to content

Commit fe03383

Browse files
committed
Track in-flight event requests
1 parent 5cb25d9 commit fe03383

File tree

2 files changed

+80
-8
lines changed

2 files changed

+80
-8
lines changed

bugsnag/client.py

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from bugsnag.sessiontracker import SessionTracker
2020
from bugsnag.utils import to_rfc3339
2121
from bugsnag.context import ContextLocalState
22+
from bugsnag.request_tracker import RequestTracker
2223

2324
__all__ = ('Client',)
2425

@@ -36,6 +37,7 @@ def __init__(self, configuration: Optional[Configuration] = None,
3637
self.session_tracker = SessionTracker(self.configuration)
3738
self.configuration.configure(**kwargs)
3839
self._context = ContextLocalState(self)
40+
self._request_tracker = RequestTracker()
3941

4042
if install_sys_hook:
4143
self.install_sys_hook()
@@ -174,11 +176,6 @@ def run_middleware():
174176
initial_reason = event.severity_reason.copy()
175177

176178
def send_payload():
177-
if asynchronous is None:
178-
options = {}
179-
else:
180-
options = {'asynchronous': asynchronous}
181-
182179
if event.api_key is None:
183180
self.configuration.logger.warning(
184181
"No API key configured, couldn't notify"
@@ -192,16 +189,30 @@ def send_payload():
192189
}
193190
else:
194191
event.severity_reason = initial_reason
192+
195193
payload = event._payload()
194+
195+
post_delivery_callback = self._request_tracker.new_request()
196+
options = {'post_delivery_callback': post_delivery_callback}
197+
198+
if asynchronous is not None:
199+
options['asynchronous'] = asynchronous
200+
196201
try:
197-
self.configuration.delivery.deliver(self.configuration,
198-
payload, options)
202+
self.configuration.delivery.deliver(
203+
self.configuration,
204+
payload,
205+
options
206+
)
199207
except Exception as e:
200208
self.configuration.logger.exception(
201209
'Notifying Bugsnag failed %s',
202210
e
203211
)
204212

213+
# ensure this request is not still marked as in-flight
214+
post_delivery_callback()
215+
205216
# Trigger session delivery
206217
self.session_tracker.send_sessions()
207218

tests/test_client.py

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,12 @@
1717
)
1818

1919
import bugsnag.legacy as legacy
20-
from tests.utils import IntegrationTest, ScaryException
20+
from tests.utils import (
21+
BrokenDelivery,
22+
IntegrationTest,
23+
QueueingDelivery,
24+
ScaryException,
25+
)
2126

2227
timestamp_regex = r'^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}(?:[+-]\d{2}:\d{2}|Z)' # noqa: E501
2328

@@ -1688,6 +1693,62 @@ def on_error(event):
16881693
FeatureFlag('e')
16891694
]
16901695

1696+
def test_in_flight_event_request_tracking_in_notify(self):
1697+
delivery = QueueingDelivery()
1698+
configuration = Configuration()
1699+
configuration.configure(delivery=delivery, api_key='abc')
1700+
1701+
client = Client(configuration)
1702+
assert not client._request_tracker.has_in_flight_requests()
1703+
1704+
client.notify(Exception('Oh no'))
1705+
assert client._request_tracker.has_in_flight_requests()
1706+
1707+
delivery.flush_request_queue()
1708+
assert not client._request_tracker.has_in_flight_requests()
1709+
1710+
def test_in_flight_event_request_tracking_in_notify_failure(self):
1711+
configuration = Configuration()
1712+
configuration.configure(delivery=BrokenDelivery(), api_key='abc')
1713+
1714+
client = Client(configuration)
1715+
assert not client._request_tracker.has_in_flight_requests()
1716+
1717+
client.notify(Exception('Oh no'))
1718+
assert not client._request_tracker.has_in_flight_requests()
1719+
1720+
def test_in_flight_event_request_tracking_in_notify_exc_info(self):
1721+
delivery = QueueingDelivery()
1722+
configuration = Configuration()
1723+
configuration.configure(delivery=delivery, api_key='abc')
1724+
1725+
client = Client(configuration)
1726+
assert not client._request_tracker.has_in_flight_requests()
1727+
1728+
try:
1729+
raise Exception(':)')
1730+
except Exception:
1731+
client.notify_exc_info(*sys.exc_info())
1732+
1733+
assert client._request_tracker.has_in_flight_requests()
1734+
1735+
delivery.flush_request_queue()
1736+
assert not client._request_tracker.has_in_flight_requests()
1737+
1738+
def test_in_flight_event_request_tracking_in_notify_exc_info_failure(self):
1739+
configuration = Configuration()
1740+
configuration.configure(delivery=BrokenDelivery(), api_key='abc')
1741+
1742+
client = Client(configuration)
1743+
assert not client._request_tracker.has_in_flight_requests()
1744+
1745+
try:
1746+
raise Exception(':)')
1747+
except Exception:
1748+
client.notify_exc_info(*sys.exc_info())
1749+
1750+
assert not client._request_tracker.has_in_flight_requests()
1751+
16911752

16921753
@pytest.mark.parametrize("metadata,type", [
16931754
(1234, 'int'),

0 commit comments

Comments
 (0)