Fixed #20445 -- Raised original exception after command error

This commit is contained in:
Jorge Bastida 2013-05-18 18:04:45 +02:00 committed by Claude Paroz
parent 4280217f31
commit 888c86dcf3
2 changed files with 19 additions and 17 deletions

View File

@ -7,7 +7,6 @@ import os
import sys import sys
from optparse import make_option, OptionParser from optparse import make_option, OptionParser
import traceback
import django import django
from django.core.exceptions import ImproperlyConfigured from django.core.exceptions import ImproperlyConfigured
@ -171,7 +170,7 @@ class BaseCommand(object):
make_option('--pythonpath', make_option('--pythonpath',
help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".'), help='A directory to add to the Python path, e.g. "/home/djangoprojects/myproject".'),
make_option('--traceback', action='store_true', make_option('--traceback', action='store_true',
help='Print traceback on exception'), help='Raise on exception'),
) )
help = '' help = ''
args = '' args = ''
@ -231,7 +230,8 @@ class BaseCommand(object):
Set up any environment changes requested (e.g., Python path Set up any environment changes requested (e.g., Python path
and Django settings), then run this command. If the and Django settings), then run this command. If the
command raises a ``CommandError``, intercept it and print it sensibly command raises a ``CommandError``, intercept it and print it sensibly
to stderr. to stderr. If the ``--traceback`` option is present or the raised
``Exception`` is not ``CommandError``, raise it.
""" """
parser = self.create_parser(argv[0], argv[1]) parser = self.create_parser(argv[0], argv[1])
options, args = parser.parse_args(argv[2:]) options, args = parser.parse_args(argv[2:])
@ -239,12 +239,12 @@ class BaseCommand(object):
try: try:
self.execute(*args, **options.__dict__) self.execute(*args, **options.__dict__)
except Exception as e: except Exception as e:
if options.traceback or not isinstance(e, CommandError):
raise
# 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 or not isinstance(e, CommandError): stderr.write('%s: %s' % (e.__class__.__name__, e))
stderr.write(traceback.format_exc())
else:
stderr.write('%s: %s' % (e.__class__.__name__, e))
sys.exit(1) sys.exit(1)
def execute(self, *args, **options): def execute(self, *args, **options):

View File

@ -1305,13 +1305,15 @@ class CommandTypes(AdminScriptTestCase):
sys.stderr = err = StringIO() sys.stderr = err = StringIO()
try: try:
command.execute = lambda args: args # This will trigger TypeError command.execute = lambda args: args # This will trigger TypeError
with self.assertRaises(SystemExit):
command.run_from_argv(['', ''])
err_message = err.getvalue()
# Exceptions other than CommandError automatically output the traceback
self.assertIn("Traceback", err_message)
self.assertIn("TypeError", err_message)
# If the Exception is not CommandError it should always
# raise the original exception.
with self.assertRaises(TypeError):
command.run_from_argv(['', ''])
# If the Exception is CommandError and --traceback is not present
# this command should raise a SystemExit and don't print any
# traceback to the stderr.
command.execute = raise_command_error command.execute = raise_command_error
err.truncate(0) err.truncate(0)
with self.assertRaises(SystemExit): with self.assertRaises(SystemExit):
@ -1320,12 +1322,12 @@ class CommandTypes(AdminScriptTestCase):
self.assertNotIn("Traceback", err_message) self.assertNotIn("Traceback", err_message)
self.assertIn("CommandError", err_message) self.assertIn("CommandError", err_message)
# If the Exception is CommandError and --traceback is present
# this command should raise the original CommandError as if it
# were not a CommandError.
err.truncate(0) err.truncate(0)
with self.assertRaises(SystemExit): with self.assertRaises(CommandError):
command.run_from_argv(['', '', '--traceback']) command.run_from_argv(['', '', '--traceback'])
err_message = err.getvalue()
self.assertIn("Traceback (most recent call last)", err_message)
self.assertIn("CommandError", err_message)
finally: finally:
sys.stderr = old_stderr sys.stderr = old_stderr