Skip to content

Commit

Permalink
Add Client.captureExceptions context manager
Browse files Browse the repository at this point in the history
  • Loading branch information
dcramer committed Aug 7, 2012
1 parent 3745322 commit a195450
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
24 changes: 24 additions & 0 deletions raven/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,21 @@ def did_fail(self):
return self.status == self.ERROR


class ExceptionContextManager(object):
def __init__(self, client, **kwargs):
self.client = client
self.kwargs = kwargs
self.result = None

def __enter__(self):
return self

def __exit__(self, *exc_info):
if not exc_info or not all(exc_info):
return
self.result = self.client.captureException(exc_info=exc_info, **self.kwargs)


class Client(object):
"""
The base Raven client, which handles both local direct
Expand Down Expand Up @@ -520,6 +535,15 @@ def captureQuery(self, query, params=(), engine=None, **kwargs):
return self.capture('Query', query=query, params=params, engine=engine,
**kwargs)

def captureExceptions(self, **kwargs):
"""
Captures any exceptions within the executed scope.
>>> with client.captureExceptions(tags={'foo': 'bar'})
>>> 1 / 0
"""
return ExceptionContextManager(self, **kwargs)


class DummyClient(Client):
"Sends messages into an empty void"
Expand Down
30 changes: 30 additions & 0 deletions tests/client/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,36 @@ def test_message_event(self):
self.assertFalse('sentry.interfaces.Stacktrace' in event)
self.assertTrue('timestamp' in event)

def test_exception_context_manager(self):
try:
cm = self.client.captureExceptions(tags={'foo': 'bar'})
with cm:
raise ValueError('foo')
except:
pass
else:
self.fail('Exception should have been raised')

self.assertNotEquals(cm.result, None)

self.assertEquals(len(self.client.events), 1)
event = self.client.events.pop(0)
self.assertEquals(event['message'], 'ValueError: foo')
self.assertTrue('sentry.interfaces.Exception' in event)
exc = event['sentry.interfaces.Exception']
self.assertEquals(exc['type'], 'ValueError')
self.assertEquals(exc['value'], 'foo')
self.assertEquals(exc['module'], ValueError.__module__) # this differs in some Python versions
self.assertTrue('sentry.interfaces.Stacktrace' in event)
frames = event['sentry.interfaces.Stacktrace']
self.assertEquals(len(frames['frames']), 1)
frame = frames['frames'][0]
self.assertEquals(frame['abs_path'], __file__.replace('.pyc', '.py'))
self.assertEquals(frame['filename'], 'tests/client/tests.py')
self.assertEquals(frame['module'], __name__)
self.assertEquals(frame['function'], 'test_exception_context_manager')
self.assertTrue('timestamp' in event)

def test_stack_explicit_frames(self):
def bar():
return inspect.stack()
Expand Down

0 comments on commit a195450

Please sign in to comment.