Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release v4.6.2 #374

Merged
merged 5 commits into from
Mar 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading