Fix unicode issue in shell.main() error handling

shell.main() uses safe_encode() to encode the exception name and
exception message. On Python 3, it displays:

   ERROR (b'Exception'): b'message'

instead of:

   ERROR (Exception): message

Don't encode exception name and message on Python 3. Use
exception_to_unicode() of oslo_utils.encodeutils to get the exception
message as Unicode. On Python 2, let print() encodes the Unicode to
the encoding of sys.stderr.

Blueprint nova-python3
Change-Id: Ib5568546d2aedb2b28c05d840b9ba34f697384ec
This commit is contained in:
Victor Stinner 2015-09-14 15:44:43 +02:00
parent 37d1e29a0b
commit 48f9c5a046
2 changed files with 15 additions and 7 deletions

View File

@ -31,7 +31,6 @@ from keystoneclient import session as ksession
from oslo_utils import encodeutils
from oslo_utils import importutils
from oslo_utils import strutils
import six
HAS_KEYRING = False
all_errors = ValueError
@ -897,12 +896,11 @@ def main():
try:
argv = [encodeutils.safe_decode(a) for a in sys.argv[1:]]
OpenStackComputeShell().main(argv)
except Exception as e:
logger.debug(e, exc_info=1)
details = {'name': encodeutils.safe_encode(e.__class__.__name__),
'msg': encodeutils.safe_encode(six.text_type(e))}
print("ERROR (%(name)s): %(msg)s" % details,
except Exception as exc:
logger.debug(exc, exc_info=1)
print("ERROR (%s): %s"
% (exc.__class__.__name__,
encodeutils.exception_to_unicode(exc)),
file=sys.stderr)
sys.exit(1)
except KeyboardInterrupt:

View File

@ -521,6 +521,16 @@ class ShellTest(utils.TestCase):
self.assertEqual(password, 'password')
self.assertIs(client_kwargs['session'], None)
@mock.patch.object(novaclient.shell.OpenStackComputeShell, 'main')
def test_main_error_handling(self, mock_compute_shell):
class MyException(Exception):
pass
with mock.patch('sys.stderr', six.StringIO()):
mock_compute_shell.side_effect = MyException('message')
self.assertRaises(SystemExit, novaclient.shell.main)
err = sys.stderr.getvalue()
self.assertEqual(err, 'ERROR (MyException): message\n')
class TestLoadVersionedActions(utils.TestCase):