summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pecan/core.py25
-rw-r--r--pecan/tests/test_base.py15
2 files changed, 34 insertions, 6 deletions
diff --git a/pecan/core.py b/pecan/core.py
index a6525ca..14b9ad3 100644
--- a/pecan/core.py
+++ b/pecan/core.py
@@ -8,6 +8,7 @@ from mimetypes import guess_type, add_type
from os.path import splitext
import logging
import operator
+import sys
import types
import six
@@ -123,12 +124,24 @@ def abort(status_code=None, detail='', headers=None, comment=None, **kw):
:param comment: A comment to include in the response.
'''
- raise exc.status_map[status_code](
- detail=detail,
- headers=headers,
- comment=comment,
- **kw
- )
+ # If there is a traceback, we need to catch it for a re-raise
+ try:
+ _, _, traceback = sys.exc_info()
+ webob_exception = exc.status_map[status_code](
+ detail=detail,
+ headers=headers,
+ comment=comment,
+ **kw
+ )
+
+ if six.PY3:
+ raise webob_exception.with_traceback(traceback)
+ else:
+ # Using exec to avoid python 3 parsers from crashing
+ exec('raise webob_exception, None, traceback')
+ finally:
+ # Per the suggestion of the Python docs, delete the traceback object
+ del traceback
def redirect(location=None, internal=False, code=None, headers={},
diff --git a/pecan/tests/test_base.py b/pecan/tests/test_base.py
index e6adf0e..785b522 100644
--- a/pecan/tests/test_base.py
+++ b/pecan/tests/test_base.py
@@ -3,6 +3,7 @@
import sys
import os
import json
+import traceback
import warnings
import webob
@@ -1121,6 +1122,20 @@ class TestAbort(PecanTestCase):
r = app.get('/', status=401)
assert r.status_int == 401
+ def test_abort_keeps_traceback(self):
+ last_exc, last_traceback = None, None
+
+ try:
+ try:
+ raise Exception('Bottom Exception')
+ except:
+ abort(404)
+ except Exception:
+ last_exc, _, last_traceback = sys.exc_info()
+
+ assert last_exc is HTTPNotFound
+ assert 'Bottom Exception' in traceback.format_tb(last_traceback)[-1]
+
class TestScriptName(PecanTestCase):