diff --git a/heat/api/middleware/fault.py b/heat/api/middleware/fault.py index eda705c42c..466ef92e4a 100644 --- a/heat/api/middleware/fault.py +++ b/heat/api/middleware/fault.py @@ -94,10 +94,10 @@ class FaultWrapper(wsgi.Middleware): if ex_type.endswith(rpc_common._REMOTE_POSTFIX): ex_type = ex_type[:-len(rpc_common._REMOTE_POSTFIX)] - message = str(ex.message) + message = unicode(ex.message) if cfg.CONF.debug and not trace: - trace = str(ex) + trace = unicode(ex) if trace.find('\n') > -1: unused, trace = trace.split('\n', 1) else: diff --git a/heat/common/exception.py b/heat/common/exception.py index 22bc4f8ead..170ba70823 100644 --- a/heat/common/exception.py +++ b/heat/common/exception.py @@ -120,6 +120,9 @@ class HeatException(Exception): def __str__(self): return str(self.message) + def __unicode__(self): + return unicode(self.message) + class MissingCredentialError(HeatException): message = _("Missing required credential: %(required)s") diff --git a/heat/tests/test_fault_middleware.py b/heat/tests/test_fault_middleware.py index 9fe55191ec..b2c079c427 100644 --- a/heat/tests/test_fault_middleware.py +++ b/heat/tests/test_fault_middleware.py @@ -47,6 +47,26 @@ class FaultMiddlewareTest(HeatTestCase): 'title': 'Internal Server Error'} self.assertEqual(msg, expected) + def test_exception_with_non_ascii_chars(self): + # We set debug to true to test the code path for serializing traces too + cfg.CONF.set_override('debug', True) + msg = u'Error with non-ascii chars \x80' + + class TestException(heat_exc.HeatException): + message = msg + + wrapper = fault.FaultWrapper(None) + msg = wrapper._error(TestException()) + expected = {'code': 500, + 'error': {'message': u'Error with non-ascii chars \x80', + 'traceback': 'None\n', + 'type': 'TestException'}, + 'explanation': ('The server has either erred or is ' + 'incapable of performing the requested ' + 'operation.'), + 'title': 'Internal Server Error'} + self.assertEqual(msg, expected) + def test_remote_exception(self): # We want tracebacks cfg.CONF.set_override('debug', True)