Kaydet (Commit) 6a91b638 authored tarafından Claude Paroz's avatar Claude Paroz

Fixed #19923 -- Display tracebacks for non-CommandError exceptions

By default, show tracebacks for management command errors when the
exception is not a CommandError.
Thanks Jacob Radford for the report.
üst 5e80571b
...@@ -241,7 +241,7 @@ class BaseCommand(object): ...@@ -241,7 +241,7 @@ class BaseCommand(object):
except Exception as e: except Exception as e:
# self.stderr is not guaranteed to be set here # self.stderr is not guaranteed to be set here
stderr = getattr(self, 'stderr', OutputWrapper(sys.stderr, self.style.ERROR)) stderr = getattr(self, 'stderr', OutputWrapper(sys.stderr, self.style.ERROR))
if options.traceback: if options.traceback or not isinstance(e, CommandError):
stderr.write(traceback.format_exc()) stderr.write(traceback.format_exc())
else: else:
stderr.write('%s: %s' % (e.__class__.__name__, e)) stderr.write('%s: %s' % (e.__class__.__name__, e))
......
...@@ -1342,8 +1342,13 @@ Example usage:: ...@@ -1342,8 +1342,13 @@ Example usage::
django-admin.py syncdb --traceback django-admin.py syncdb --traceback
By default, ``django-admin.py`` will show a simple error message whenever an By default, ``django-admin.py`` will show a simple error message whenever an
error occurs. If you specify ``--traceback``, ``django-admin.py`` will :class:`~django.core.management.CommandError` occurs, but a full stack trace
output a full stack trace whenever an exception is raised. for any other exception. If you specify ``--traceback``, ``django-admin.py``
will also output a full stack trace when a ``CommandError`` is raised.
.. versionchanged:: 1.6
Previously, Django didn't show a full stack trace by default for exceptions
other than ``CommandError``.
.. django-admin-option:: --verbosity .. django-admin-option:: --verbosity
......
...@@ -16,7 +16,7 @@ import codecs ...@@ -16,7 +16,7 @@ import codecs
from django import conf, bin, get_version from django import conf, bin, get_version
from django.conf import settings from django.conf import settings
from django.core.management import BaseCommand from django.core.management import BaseCommand, CommandError
from django.db import connection from django.db import connection
from django.test.simple import DjangoTestSuiteRunner from django.test.simple import DjangoTestSuiteRunner
from django.utils import unittest from django.utils import unittest
...@@ -1297,22 +1297,34 @@ class CommandTypes(AdminScriptTestCase): ...@@ -1297,22 +1297,34 @@ class CommandTypes(AdminScriptTestCase):
Also test proper traceback display. Also test proper traceback display.
""" """
command = BaseCommand() command = BaseCommand()
command.execute = lambda args: args # This will trigger TypeError def raise_command_error(*args, **kwargs):
raise CommandError("Custom error")
old_stderr = sys.stderr old_stderr = sys.stderr
sys.stderr = err = StringIO() sys.stderr = err = StringIO()
try: try:
command.execute = lambda args: args # This will trigger TypeError
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
command.run_from_argv(['', '']) command.run_from_argv(['', ''])
err_message = err.getvalue() err_message = err.getvalue()
self.assertNotIn("Traceback", err_message) # Exceptions other than CommandError automatically output the traceback
self.assertIn("Traceback", err_message)
self.assertIn("TypeError", err_message) self.assertIn("TypeError", err_message)
command.execute = raise_command_error
err.truncate(0)
with self.assertRaises(SystemExit):
command.run_from_argv(['', ''])
err_message = err.getvalue()
self.assertNotIn("Traceback", err_message)
self.assertIn("CommandError", err_message)
err.truncate(0)
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
command.run_from_argv(['', '', '--traceback']) command.run_from_argv(['', '', '--traceback'])
err_message = err.getvalue() err_message = err.getvalue()
self.assertIn("Traceback (most recent call last)", err_message) self.assertIn("Traceback (most recent call last)", err_message)
self.assertIn("TypeError", err_message) self.assertIn("CommandError", err_message)
finally: finally:
sys.stderr = old_stderr sys.stderr = old_stderr
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment