Permalink
Browse files

Added static publish() method for Exceptional tracking outside the co…

…ntext of a request.
  • Loading branch information...
jzempel committed Nov 10, 2011
1 parent 0b8e2eb commit a005ec6ce0ee8314735847ebeeac55d9ecf06e6f
Showing with 62 additions and 10 deletions.
  1. +42 −9 flaskext/exceptional.py
  2. +1 −1 setup.py
  3. +19 −0 tests.py
View
@@ -93,6 +93,29 @@ def init_app(self, app):
else:
app.logger.warning("Missing 'EXCEPTIONAL_API_KEY' configuration.")
+ @staticmethod
+ def publish(config, traceback):
+ """Publish the given traceback directly to Exceptional. This method is
+ useful for tracking errors that occur outside the context of a Flask
+ request. For example, this may be called from an asynchronous queue.
+
+ :param config: A Flask application configuration object. Accepts either
+ :class:`flask.Config` or the object types allowed by
+ :meth:`flask.Config.from_object`.
+ :param traceback: A :class:`werkzeug.debug.tbtools.Traceback` instance
+ to publish.
+ """
+ app = Flask(__name__)
+ exceptional = Exceptional()
+
+ if isinstance(config, Config):
+ app.config = config
+ else:
+ app.config.from_object(config)
+
+ exceptional.init_app(app)
+ exceptional._post_data(traceback=traceback)
+
@staticmethod
def test(config):
"""Test the given Flask configuration. If configured correctly,
@@ -164,34 +187,44 @@ def ret_val(exception):
return ret_val
- def _post_data(self, context):
+ def _post_data(self, context=None, traceback=None):
"""POST data to the the Exceptional API. If DEBUG is True then data is
sent to ``EXCEPTIONAL_DEBUG_URL`` if it has been defined. If TESTING is
true, error data is stored in the global ``flask.g.exceptional`` variable.
- :param context: The current application context.
+ :param context: Default ``None``. The current application context.
+ :param traceback: Default ``None``. The exception stack trace.
"""
+ app = context.app if context else self.app
+ application_data = self.__get_application_data(app)
client_data = {
"name": "flask-exceptional",
"version": self.__version__,
"protocol_version": self.__protocol_version
}
- traceback = tbtools.get_current_traceback()
+
+ if context:
+ request_data = self.__get_request_data(app, context.request, context.session)
+ else:
+ request_data = None
+
+ traceback = traceback or tbtools.get_current_traceback()
+ exception_data = self.__get_exception_data(traceback)
error_data = json.dumps({
- "application_environment": self.__get_application_data(context.app),
+ "application_environment": application_data,
"client": client_data,
- "request": self.__get_request_data(context.app, context.request, context.session),
- "exception": self.__get_exception_data(traceback)
+ "request": request_data,
+ "exception": exception_data
})
- if context.app.testing:
+ if app.testing:
g.exceptional = error_data
if self.url:
request = Request(self.url)
request.add_header("Content-Type", "application/json")
- if context.app.debug:
+ if app.debug:
data = error_data
else:
request.add_header("Content-Encoding", "deflate")
@@ -212,7 +245,7 @@ def _post_data(self, context):
def __filter(app, data, filter_name):
"""Filter sensitive data.
"""
- filter = app.config[filter_name]
+ filter = app.config.get(filter_name)
if filter:
ret_val = {}
View
@@ -25,7 +25,7 @@
setup(
name='Flask-Exceptional',
- version='0.4.6',
+ version='0.4.7',
url='http://github.com/jzempel/flask-exceptional',
license='BSD',
author='Jonathan Zempel',
View
@@ -13,6 +13,8 @@
from flask import abort, Flask, g, json
from flaskext.exceptional import Exceptional
from os import environ
+from sys import exc_info
+from werkzeug.debug.tbtools import Traceback
import unittest
class ExceptionalTestCase(unittest.TestCase):
@@ -161,6 +163,23 @@ def test_09_debug(self):
json.loads(g.exceptional)
print "See %s for HTTP request details." % exceptional.url
+ def test_10_publish(self):
+ """Test direct exception publishing.
+ """
+ self.app = self.create_application()
+
+ try:
+ raise ValueError
+ except ValueError:
+ type, exception, traceback = exc_info()
+ traceback = Traceback(type, exception, traceback)
+
+ with self.app.test_request_context():
+ Exceptional.publish(self.app.config, traceback)
+ data = json.loads(g.exceptional)
+ exception = data["exception"]
+ assert exception["exception_class"] == ValueError.__name__
+
if __name__ == "__main__":
unittest.main()

0 comments on commit a005ec6

Please sign in to comment.