Improve handling of unicode errors

Fixes #12669
This commit is contained in:
James Cammarata 2015-10-08 10:04:15 -04:00
parent 5a0f5f1254
commit de792ba3c2
3 changed files with 24 additions and 5 deletions

View file

@ -38,6 +38,7 @@ import traceback
from ansible.errors import AnsibleError, AnsibleOptionsError, AnsibleParserError
from ansible.utils.display import Display
from ansible.utils.unicode import to_unicode
########################################
### OUTPUT OF LAST RESORT ###
@ -82,10 +83,10 @@ if __name__ == '__main__':
except AnsibleOptionsError as e:
cli.parser.print_help()
display.error(str(e), wrap_text=False)
display.error(to_unicode(e), wrap_text=False)
sys.exit(5)
except AnsibleParserError as e:
display.error(str(e), wrap_text=False)
display.error(to_unicode(e), wrap_text=False)
sys.exit(4)
# TQM takes care of these, but leaving comment to reserve the exit codes
# except AnsibleHostUnreachable as e:
@ -95,14 +96,14 @@ if __name__ == '__main__':
# display.error(str(e))
# sys.exit(2)
except AnsibleError as e:
display.error(str(e), wrap_text=False)
display.error(to_unicode(e), wrap_text=False)
sys.exit(1)
except KeyboardInterrupt:
display.error("User interrupted execution")
sys.exit(99)
except Exception as e:
have_cli_options = cli is not None and cli.options is not None
display.error("Unexpected Exception: %s" % str(e), wrap_text=False)
display.error("Unexpected Exception: %s" % to_unicode(e), wrap_text=False)
if not have_cli_options or have_cli_options and cli.options.verbosity > 2:
display.display("the full traceback was:\n\n%s" % traceback.format_exc())
else:

View file

@ -22,6 +22,7 @@ __metaclass__ = type
import os
from ansible.errors.yaml_strings import *
from ansible.utils.unicode import to_unicode, to_bytes
class AnsibleError(Exception):
'''
@ -48,7 +49,7 @@ class AnsibleError(Exception):
if obj and isinstance(obj, AnsibleBaseYAMLObject):
extended_error = self._get_extended_error()
if extended_error:
self.message = 'ERROR! %s\n\n%s' % (message, extended_error)
self.message = 'ERROR! %s\n\n%s' % (message, to_bytes(extended_error))
else:
self.message = 'ERROR! %s' % message
@ -96,6 +97,8 @@ class AnsibleError(Exception):
error_message += YAML_POSITION_DETAILS % (src_file, line_number, col_number)
if src_file not in ('<string>', '<unicode>') and self._show_content:
(target_line, prev_line) = self._get_error_lines_from_file(src_file, line_number - 1)
target_line = to_unicode(target_line)
prev_line = to_unicode(prev_line)
if target_line:
stripped_line = target_line.replace(" ","")
arrow_line = (" " * (col_number-1)) + "^ here"

View file

@ -31,6 +31,7 @@ class TestErrors(unittest.TestCase):
def setUp(self):
self.message = 'This is the error message'
self.unicode_message = 'This is an error with \xf0\x9f\x98\xa8 in it'
self.obj = AnsibleBaseYAMLObject()
@ -42,6 +43,11 @@ class TestErrors(unittest.TestCase):
self.assertEqual(e.message, 'ERROR! ' + self.message)
self.assertEqual(e.__repr__(), 'ERROR! ' + self.message)
def test_basic_unicode_error(self):
e = AnsibleError(self.unicode_message)
self.assertEqual(e.message, 'ERROR! ' + self.unicode_message)
self.assertEqual(e.__repr__(), 'ERROR! ' + self.unicode_message)
@patch.object(AnsibleError, '_get_error_lines_from_file')
def test_error_with_object(self, mock_method):
self.obj.ansible_pos = ('foo.yml', 1, 1)
@ -66,3 +72,12 @@ class TestErrors(unittest.TestCase):
e = AnsibleError(self.message, self.obj)
self.assertEqual(e.message, "ERROR! This is the error message\n\nThe error appears to have been in 'foo.yml': line 2, column 1, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\n(specified line no longer in file, maybe it changed?)")
m = mock_open()
m.return_value.readlines.return_value = ['this line has unicode \xf0\x9f\x98\xa8 in it!\n']
with patch('{0}.open'.format(BUILTINS), m):
# this line will be found in the file
self.obj.ansible_pos = ('foo.yml', 1, 1)
e = AnsibleError(self.unicode_message, self.obj)
self.assertEqual(e.message, "ERROR! This is an error with \xf0\x9f\x98\xa8 in it\n\nThe error appears to have been in 'foo.yml': line 1, column 1, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\nthis line has unicode \xf0\x9f\x98\xa8 in it!\n^ here\n")