|
@@ -766,6 +766,79 @@ class ExceptionReporterTests(SimpleTestCase):
|
|
|
self.assertIn(implicit_exc.format("<p>Second exception</p>"), text)
|
|
|
self.assertEqual(3, text.count("<p>Final exception</p>"))
|
|
|
|
|
|
+ @skipIf(
|
|
|
+ sys._xoptions.get("no_debug_ranges", False)
|
|
|
+ or os.environ.get("PYTHONNODEBUGRANGES", False),
|
|
|
+ "Fine-grained error locations are disabled.",
|
|
|
+ )
|
|
|
+ @skipUnless(PY311, "Fine-grained error locations were added in Python 3.11.")
|
|
|
+ def test_highlight_error_position(self):
|
|
|
+ request = self.rf.get("/test_view/")
|
|
|
+ try:
|
|
|
+ try:
|
|
|
+ raise AttributeError("Top level")
|
|
|
+ except AttributeError as explicit:
|
|
|
+ try:
|
|
|
+ raise ValueError(mark_safe("<p>2nd exception</p>")) from explicit
|
|
|
+ except ValueError:
|
|
|
+ raise IndexError("Final exception")
|
|
|
+ except Exception:
|
|
|
+ exc_type, exc_value, tb = sys.exc_info()
|
|
|
+
|
|
|
+ reporter = ExceptionReporter(request, exc_type, exc_value, tb)
|
|
|
+ html = reporter.get_traceback_html()
|
|
|
+ self.assertIn(
|
|
|
+ "<pre> raise AttributeError("Top level")\n"
|
|
|
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^</pre>",
|
|
|
+ html,
|
|
|
+ )
|
|
|
+ self.assertIn(
|
|
|
+ "<pre> raise ValueError(mark_safe("
|
|
|
+ ""<p>2nd exception</p>")) from explicit\n"
|
|
|
+ " "
|
|
|
+ "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^</pre>",
|
|
|
+ html,
|
|
|
+ )
|
|
|
+ self.assertIn(
|
|
|
+ "<pre> raise IndexError("Final exception")\n"
|
|
|
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^</pre>",
|
|
|
+ html,
|
|
|
+ )
|
|
|
+ # Pastebin.
|
|
|
+ self.assertIn(
|
|
|
+ " raise AttributeError("Top level")\n"
|
|
|
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
|
|
|
+ html,
|
|
|
+ )
|
|
|
+ self.assertIn(
|
|
|
+ " raise ValueError(mark_safe("
|
|
|
+ ""<p>2nd exception</p>")) from explicit\n"
|
|
|
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
|
|
|
+ html,
|
|
|
+ )
|
|
|
+ self.assertIn(
|
|
|
+ " raise IndexError("Final exception")\n"
|
|
|
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
|
|
|
+ html,
|
|
|
+ )
|
|
|
+ # Text traceback.
|
|
|
+ text = reporter.get_traceback_text()
|
|
|
+ self.assertIn(
|
|
|
+ ' raise AttributeError("Top level")\n'
|
|
|
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
|
|
|
+ text,
|
|
|
+ )
|
|
|
+ self.assertIn(
|
|
|
+ ' raise ValueError(mark_safe("<p>2nd exception</p>")) from explicit\n'
|
|
|
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
|
|
|
+ text,
|
|
|
+ )
|
|
|
+ self.assertIn(
|
|
|
+ ' raise IndexError("Final exception")\n'
|
|
|
+ " ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n",
|
|
|
+ text,
|
|
|
+ )
|
|
|
+
|
|
|
def test_reporting_frames_without_source(self):
|
|
|
try:
|
|
|
source = "def funcName():\n raise Error('Whoops')\nfuncName()"
|