Reputation: 1067
I'm using apscheduler to process few things in background.
I'd like to capture and report possible exceptions to Sentry. My code looks like this:
sentry = Client(dsn=SENTRY_DSN)
def sample_method():
# some processing..
raise ConnectionError
def listen_to_exceptions(event):
if event.exception:
# I was hoping raven will capture the exception using sys.exc_info(), but it's not
sentry.captureException()
scheduler = BlockingScheduler()
scheduler.add_listener(listen_to_exceptions, EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
scheduler.add_job(sample_method, 'interval', minutes=5, max_instances=1)
# run forever!!!
scheduler.start()
But instead capturing the exception, it generates more exceptions trying to report it to Sentry.
ConnectionError
Error notifying listener
Traceback (most recent call last):
File "/.../venv/lib/python3.6/site-packages/apscheduler/schedulers/base.py", line 825, in _dispatch_event
cb(event)
File "app.py", line 114, in listen_to_exceptions
sentry.captureException(event.exception)
File "/.../venv/lib/python3.6/site-packages/raven/base.py", line 814, in captureException
'raven.events.Exception', exc_info=exc_info, **kwargs)
File "/.../venv/lib/python3.6/site-packages/raven/base.py", line 623, in capture
if self.skip_error_for_logging(exc_info):
File "/.../venv/lib/python3.6/site-packages/raven/base.py", line 358, in skip_error_for_logging
key = self._get_exception_key(exc_info)
File "/.../venv/lib/python3.6/site-packages/raven/base.py", line 345, in _get_exception_key
code_id = id(exc_info[2] and exc_info[2].tb_frame.f_code)
TypeError: 'ConnectionError' object is not subscriptable
I'm trying to use event listener according to the docs. Is there another way to capture exceptions in executed jobs?
Of course I could add try except blocks to each job function. I'm just trying to understand if there's a way to do it with apscedular, because I've 20+ jobs and adding sentry.captureException()
every where seems like repetition.
Upvotes: 0
Views: 1794
Reputation: 721
The documentation has been updated. So you have to do it the following way:
from sentry_sdk import capture_exception
....
def sentry_listener(event):
if event.exception:
capture_exception(event.exception)
scheduler.add_listener(sentry_listener, EVENT_JOB_ERROR)
Upvotes: 3
Reputation: 5901
You only need to capture EVENT_JOB_ERROR
. Also, sentry.captureException()
requires an exc_info tuple as its argument, not the exception object. The following will work on Python 3:
def listen_to_exceptions(event):
exc_info = type(event.exception), event.exception, event.exception.__traceback__
sentry.captureException(exc_info)
scheduler.add_listener(listen_to_exceptions, EVENT_JOB_ERROR)
Upvotes: 3