Skip to content

Commit

Permalink
Release v4.6.2
Browse files Browse the repository at this point in the history
  • Loading branch information
imjoehaines authored Mar 5, 2024
2 parents b22ab1f + e945a99 commit e57f70c
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 18 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
Changelog
=========

## v4.6.2 (2024-03-05)

### Bug fixes

* Ensure sessions are sent at exit
[#371](https://github.com/bugsnag/bugsnag-python/pull/371)

## v4.6.1 (2023-12-11)

### Bug fixes
Expand Down
19 changes: 19 additions & 0 deletions bugsnag/configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,25 @@ def delivery(self):
def delivery(self, value):
if hasattr(value, 'deliver') and callable(value.deliver):
self._delivery = value

# deliver_sessions is _technically_ optional in that if you disable
# session tracking it will never be called
# this should be made mandatory in the next major release
if (
hasattr(value, 'deliver_sessions') and
callable(value.deliver_sessions)
):
parameter_names = value.deliver_sessions.__code__.co_varnames

if 'options' not in parameter_names:
warnings.warn(
'delivery.deliver_sessions should accept an ' +
'"options" parameter to allow for synchronous ' +
'delivery, sessions may be lost when the process ' +
'exits',
DeprecationWarning
)

else:
message = ('delivery should implement Delivery interface, got ' +
'{0}. This will be an error in a future release.')
Expand Down
24 changes: 14 additions & 10 deletions bugsnag/delivery.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,13 @@ class Delivery:
def __init__(self):
self.sent_session_warning = False

def deliver(self, config, payload: Any, options={}):
def deliver(self, config, payload: Any, options=None):
"""
Sends error reports to Bugsnag
"""
pass

def deliver_sessions(self, config, payload: Any):
def deliver_sessions(self, config, payload: Any, options=None):
"""
Sends sessions to Bugsnag
"""
Expand All @@ -72,10 +72,12 @@ def deliver_sessions(self, config, payload: Any):
'No sessions will be sent to Bugsnag.')
self.sent_session_warning = True
else:
options = {
'endpoint': config.session_endpoint,
'success': 202,
}
if options is None:
options = {}

options['endpoint'] = config.session_endpoint
options['success'] = 202

self.deliver(config, payload, options)

def queue_request(self, request: Callable, config, options: Dict):
Expand All @@ -96,8 +98,9 @@ def safe_request():


class UrllibDelivery(Delivery):

def deliver(self, config, payload: Any, options={}):
def deliver(self, config, payload: Any, options=None):
if options is None:
options = {}

def request():
uri = options.pop('endpoint', config.endpoint)
Expand Down Expand Up @@ -134,8 +137,9 @@ def request():


class RequestsDelivery(Delivery):

def deliver(self, config, payload: Any, options={}):
def deliver(self, config, payload: Any, options=None):
if options is None:
options = {}

def request():
uri = options.pop('endpoint', config.endpoint)
Expand Down
2 changes: 1 addition & 1 deletion bugsnag/notifier.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
_NOTIFIER_INFORMATION = {
'name': 'Python Bugsnag Notifier',
'url': 'https://github.com/bugsnag/bugsnag-python',
'version': '4.6.1'
'version': '4.6.2'
}
24 changes: 19 additions & 5 deletions bugsnag/sessiontracker.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def start_session(self):
_session_info.set(new_session)
self.__queue_session(start_time)

def send_sessions(self):
def send_sessions(self, asynchronous=True):
self.mutex.acquire()
try:
sessions = []
Expand All @@ -66,7 +66,8 @@ def send_sessions(self):
self.session_counts = {}
finally:
self.mutex.release()
self.__deliver(sessions)

self.__deliver(sessions, asynchronous)

def __start_delivery(self):
if self.delivery_thread is None:
Expand All @@ -83,7 +84,8 @@ def deliver():
def cleanup():
if self.delivery_thread is not None:
self.delivery_thread.cancel()
self.send_sessions()

self.send_sessions(asynchronous=False)

atexit.register(cleanup)

Expand All @@ -96,7 +98,7 @@ def __queue_session(self, start_time: str):
finally:
self.mutex.release()

def __deliver(self, sessions: List[Dict]):
def __deliver(self, sessions: List[Dict], asynchronous=True):
if not sessions:
self.config.logger.debug("No sessions to deliver")
return
Expand Down Expand Up @@ -132,7 +134,19 @@ def __deliver(self, sessions: List[Dict]):
)

encoded_payload = encoder.encode(payload)
self.config.delivery.deliver_sessions(self.config, encoded_payload)

deliver = self.config.delivery.deliver_sessions

if 'options' in deliver.__code__.co_varnames:
deliver(
self.config,
encoded_payload,
options={'asynchronous': asynchronous}
)
else:
deliver(self.config, encoded_payload)


except Exception as e:
self.config.logger.exception('Sending sessions failed %s', e)

Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

setup(
name='bugsnag',
version='4.6.1',
version='4.6.2',
description='Automatic error monitoring for django, flask, etc.',
long_description=__doc__,
author='Simon Maynard',
Expand Down
1 change: 0 additions & 1 deletion tests/integrations/test_asgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,6 @@ async def app(scope, recv, send):
self.assertEqual('GET', request['httpMethod'])
self.assertEqual('http', request['type'])
self.assertEqual('http://testserver/', request['url'])
self.assertEqual('testclient', request['clientIp'])
self.assertEqual('testclient', request['headers']['user-agent'])

exception = payload['events'][0]['exceptions'][0]
Expand Down
21 changes: 21 additions & 0 deletions tests/test_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ class BadDelivery(object):
def deliv(self, *args, **kwargs):
pass

class OkDelivery:
def deliver(self, *args, **kwargs):
pass

def deliver_sessions(self, config, payload):
pass

class GoodDelivery(object):
def deliver(self, *args, **kwargs):
pass
Expand All @@ -213,6 +220,20 @@ def deliver(self, *args, **kwargs):
assert len(record) == 1
assert c.delivery == good

with pytest.warns(DeprecationWarning) as record:
ok = OkDelivery()

c.configure(delivery=ok)

assert len(record) == 1
assert str(record[0].message) == (
'delivery.deliver_sessions should accept an "options" ' +
'parameter to allow for synchronous delivery, sessions ' +
'may be lost when the process exits'
)

assert c.delivery == ok

def test_validate_hostname(self):
c = Configuration()
with pytest.warns(RuntimeWarning) as record:
Expand Down

0 comments on commit e57f70c

Please sign in to comment.