debian-python-raven/raven/middleware.py

93 lines
3.0 KiB
Python
Raw Normal View History

2011-10-07 19:12:06 +02:00
"""
2011-10-07 19:57:45 +02:00
raven.middleware
2011-10-07 19:12:06 +02:00
~~~~~~~~~~~~~~~~~~~~~~~~
2012-10-12 19:45:54 +02:00
:copyright: (c) 2010-2012 by the Sentry Team, see AUTHORS for more details.
2011-10-07 19:12:06 +02:00
:license: BSD, see LICENSE for more details.
"""
from __future__ import absolute_import
2011-10-07 19:12:06 +02:00
from raven.utils.wsgi import (
get_current_url, get_headers, get_environ)
2011-10-07 19:12:06 +02:00
2011-10-07 19:12:06 +02:00
class Sentry(object):
"""
A WSGI middleware which will attempt to capture any
uncaught exceptions and send them to Sentry.
2011-10-07 19:57:45 +02:00
>>> from raven.base import Client
2011-10-07 19:12:06 +02:00
>>> application = Sentry(application, Client())
"""
def __init__(self, application, client=None):
2011-10-07 19:12:06 +02:00
self.application = application
if client is None:
from raven.base import Client
client = Client()
2011-10-07 19:12:06 +02:00
self.client = client
def __call__(self, environ, start_response):
2013-12-05 21:00:46 +01:00
# TODO(dcramer): ideally this is lazy, but the context helpers must
# support callbacks first
self.client.http_context(self.get_http_context(environ))
2011-10-07 19:12:06 +02:00
try:
iterable = self.application(environ, start_response)
except Exception:
self.handle_exception(environ)
raise
except KeyboardInterrupt:
self.handle_exception(environ)
raise
except SystemExit as e:
if e.code != 0:
self.handle_exception(environ)
raise
try:
for event in iterable:
yield event
2011-10-07 19:12:06 +02:00
except Exception:
self.handle_exception(environ)
2011-10-07 19:12:06 +02:00
raise
except KeyboardInterrupt:
self.handle_exception(environ)
raise
except SystemExit as e:
if e.code != 0:
self.handle_exception(environ)
raise
finally:
# wsgi spec requires iterable to call close if it exists
# see http://blog.dscpl.com.au/2012/10/obligations-for-calling-close-on.html
if iterable and hasattr(iterable, 'close') and callable(iterable.close):
try:
iterable.close()
except Exception:
self.handle_exception(environ)
except KeyboardInterrupt:
self.handle_exception(environ)
raise
except SystemExit as e:
if e.code != 0:
self.handle_exception(environ)
raise
2014-01-04 23:45:46 +01:00
self.client.context.clear()
2011-10-07 19:12:06 +02:00
2013-12-05 21:00:46 +01:00
def get_http_context(self, environ):
return {
'method': environ.get('REQUEST_METHOD'),
'url': get_current_url(environ, strip_querystring=True),
'query_string': environ.get('QUERY_STRING'),
# TODO
# 'data': environ.get('wsgi.input'),
'headers': dict(get_headers(environ)),
'env': dict(get_environ(environ)),
}
def process_response(self, request, response):
self.client.context.clear()
2013-12-05 21:00:46 +01:00
def handle_exception(self, environ=None):
return self.client.captureException()