From 687d2e967dbc7c2ba29a90c74becc539d3ac2b9d Mon Sep 17 00:00:00 2001
From: Lennart Regebro <regebro@gmail.com>
Date: Sat, 23 Feb 2013 17:41:30 +0100
Subject: [PATCH] Fixed #19827 -- Kept stacktrace in defaulttags exception
 reraising

Thanks Kronuz for the report and the initial patch.
---
 django/template/defaulttags.py           |  7 ++++---
 tests/regressiontests/templates/tests.py | 16 ++++++++++++++++
 2 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index 0c68446e05..accf5d56b9 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -416,7 +416,8 @@ class URLNode(Node):
         url = ''
         try:
             url = reverse(view_name, args=args, kwargs=kwargs, current_app=context.current_app)
-        except NoReverseMatch as e:
+        except NoReverseMatch:
+            exc_info = sys.exc_info()
             if settings.SETTINGS_MODULE:
                 project_name = settings.SETTINGS_MODULE.split('.')[0]
                 try:
@@ -428,10 +429,10 @@ class URLNode(Node):
                         # Re-raise the original exception, not the one with
                         # the path relative to the project. This makes a
                         # better error message.
-                        raise e
+                        six.reraise(*exc_info)
             else:
                 if self.asvar is None:
-                    raise e
+                    raise
 
         if self.asvar:
             context[self.asvar] = url
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index b4dc983cf2..21b7827108 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -372,6 +372,22 @@ class Templates(TestCase):
         with self.assertRaises(urlresolvers.NoReverseMatch):
             t.render(c)
 
+    @override_settings(TEMPLATE_STRING_IF_INVALID='%s is invalid', SETTINGS_MODULE='also_something')
+    def test_url_reverse_view_name(self):
+        # Regression test for #19827
+        t = Template('{% url will_not_match %}')
+        c = Context()
+        try:
+            t.render(c)
+        except urlresolvers.NoReverseMatch:
+            tb = sys.exc_info()[2]
+            depth = 0
+            while tb.tb_next is not None:
+                tb = tb.tb_next
+                depth += 1
+            self.assertTrue(depth > 5,
+                "The traceback context was lost when reraising the traceback. See #19827")
+
     def test_url_explicit_exception_for_old_syntax_at_run_time(self):
         # Regression test for #19280
         t = Template('{% url path.to.view %}')      # not quoted = old syntax