Browse Source

create_from_exception no longer supports traceback/exception, but exc_info instead. Changed logic for determining the view.

David Cramer 14 years ago
parent
commit
b47753d1df
5 changed files with 37 additions and 41 deletions
  1. 1 1
      README.rst
  2. 25 14
      sentry/client/base.py
  3. 0 23
      sentry/client/models.py
  4. 1 1
      sentry/helpers.py
  5. 10 2
      sentry/tests/tests.py

+ 1 - 1
README.rst

@@ -223,7 +223,7 @@ You can also record errors outside of handler if you want::
 	try:
 		...
 	except Exception, exc:
-		SentryClient.create_from_exception([url=None, view=None])
+		SentryClient.create_from_exception([exc_info=None, url=None, view=None])
 
 If you wish to log normal messages (useful for non-``logging`` integration)::
 

+ 25 - 14
sentry/client/base.py

@@ -5,7 +5,7 @@ except ImportError:
     import pickle
 import logging
 import sys
-import traceback as traceback_mod
+import traceback
 import urllib
 import urllib2
 import warnings
@@ -16,7 +16,7 @@ from django.utils.encoding import smart_unicode
 from django.views.debug import ExceptionReporter
 
 from sentry import settings
-from sentry.helpers import construct_checksum, varmap, transform
+from sentry.helpers import construct_checksum, varmap, transform, get_installed_apps
 
 logger = logging.getLogger('sentry.errors')
 
@@ -75,7 +75,7 @@ class SentryClient(object):
             'message': record.getMessage(),
         })
         if record.exc_info:
-            return self.create_from_exception(*record.exc_info[1:2], **kwargs)
+            return self.create_from_exception(record.exc_info, **kwargs)
 
         return self.process(
             traceback=record.exc_text,
@@ -91,18 +91,13 @@ class SentryClient(object):
             **kwargs
         )
 
-    def create_from_exception(self, exception=None, traceback=None, **kwargs):
+    def create_from_exception(self, exc_info=None, **kwargs):
         """
         Creates an error log from an exception.
         """
-        if not exception:
-            exc_type, exc_value, traceback = sys.exc_info()
-        elif not traceback:
-            warnings.warn('Using just the ``exception`` argument is deprecated, send ``traceback`` in addition.', DeprecationWarning)
-            exc_type, exc_value, traceback = sys.exc_info()
-        else:
-            exc_type = exception.__class__
-            exc_value = exception
+        if not exc_info:
+            exc_info = sys.exc_info()
+        exc_type, exc_value, exc_traceback = exc_info
 
         def to_unicode(f):
             if isinstance(f, dict):
@@ -128,9 +123,25 @@ class SentryClient(object):
                 var = var[:500] + '...'
             return var
 
-        reporter = ExceptionReporter(None, exc_type, exc_value, traceback)
+        reporter = ExceptionReporter(None, exc_type, exc_value, exc_traceback)
         frames = varmap(shorten, reporter.get_traceback_frames())
 
+        if not kwargs.get('view'):
+            # kudos to Tapz for this idea
+            modules = get_installed_apps()
+
+            def iter_tb_frames(tb):
+                while tb:
+                    yield tb.tb_frame
+                    tb = tb.tb_next
+                
+            
+            for frame in iter_tb_frames(exc_traceback):
+                if frame.f_globals['__name__'].rsplit('.', 1)[0] in modules:
+                    break
+
+            kwargs['view'] = '%s.%s' % (frame.f_globals['__name__'], frame.f_code.co_name)
+
         data = kwargs.pop('data', {}) or {}
         data['__sentry__'] = {
             'exc': map(to_unicode, [exc_type.__class__.__module__, exc_value.args, frames]),
@@ -142,7 +153,7 @@ class SentryClient(object):
                 'template': (origin.reload(), start, end, origin.name),
             })
         
-        tb_message = '\n'.join(traceback_mod.format_exception(exc_type, exc_value, traceback))
+        tb_message = '\n'.join(traceback.format_exception(exc_type, exc_value, exc_traceback))
 
         kwargs.setdefault('message', to_unicode(exc_value))
 

+ 0 - 23
sentry/client/models.py

@@ -1,5 +1,4 @@
 import sys
-import traceback
 import logging
 import warnings
 
@@ -9,7 +8,6 @@ from django.http import Http404
 
 from sentry import settings
 from sentry.client.base import SentryClient
-from sentry.helpers import get_installed_apps
 
 logger = logging.getLogger('sentry')
 
@@ -37,26 +35,6 @@ def sentry_exception_handler(sender, request=None, **kwargs):
         if transaction.is_dirty():
             transaction.rollback()
 
-        # kudos to Tapz for this idea
-        modules = get_installed_apps()
-
-        # only retrive last 10 lines
-        tb = traceback.extract_tb(exc_traceback)
-
-        # retrive final file and line number where the exception occured
-        file, line_number = tb[-1][:2]
-
-        # tiny hack to get the python path from filename
-        for (filename, line, function, text) in reversed(tb):
-            for path in sys.path:
-                if filename.startswith(path):
-                    view = '%s.%s' % (filename[len(path)+1:].replace('/', '.').replace('.py', ''), function)
-                    break
-            if view.split('.')[0] in modules:
-                break
-            else:
-                view = '%s.%s' % (exc_traceback.tb_frame.f_globals['__name__'], tb[-1][2]) 
-
         if request:
             data = dict(
                 META=request.META,
@@ -70,7 +48,6 @@ def sentry_exception_handler(sender, request=None, **kwargs):
         extra = dict(
             url=request and request.build_absolute_uri() or None,
             data=data,
-            view=view,
         )
         
         client = get_client()

+ 1 - 1
sentry/helpers.py

@@ -66,7 +66,7 @@ def get_installed_apps():
     """
     out = set()
     for app in settings.INSTALLED_APPS:
-        out.add(app.split('.')[0])
+        out.add(app)
     return out
 
 class _Missing(object):

+ 10 - 2
sentry/tests/tests.py

@@ -228,7 +228,7 @@ class SentryTestCase(TestCase):
         try:
             Message.objects.get(id=999999989)
         except Message.DoesNotExist, exc:
-            error = get_client().create_from_exception(exc)
+            error = get_client().create_from_exception()
             self.assertTrue(error.data.get('__sentry__', {}).get('exc'))
         else:
             self.fail('Unable to create `Message` entry.')
@@ -264,7 +264,7 @@ class SentryTestCase(TestCase):
         try:
             Message.objects.get(id=999999979)
         except Message.DoesNotExist, exc:
-            get_client().create_from_exception(exc)
+            get_client().create_from_exception()
         else:
             self.fail('Unable to create `Message` entry.')
             
@@ -504,6 +504,14 @@ class SentryTestCase(TestCase):
         
         settings.NAME = orig
 
+    def testExclusionViewPath(self):
+        try: Message.objects.get(pk=1341324)
+        except: get_client().create_from_exception()
+        
+        last = Message.objects.get()
+        
+        self.assertEquals(last.view, 'sentry.tests.tests.testExclusionViewPath')
+
 class SentryViewsTest(TestCase):
     urls = 'sentry.tests.urls'
     fixtures = ['sentry/tests/fixtures/views.json']