From: Ben Darnell Date: Sat, 9 Feb 2013 00:21:10 +0000 (-0500) Subject: Handle non-ascii data in logged exceptions like in the main message. X-Git-Tag: v3.0.0~137 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f6f78cbb9308612896656298f4c7c151292bf3be;p=thirdparty%2Ftornado.git Handle non-ascii data in logged exceptions like in the main message. Closes #675 --- diff --git a/tornado/log.py b/tornado/log.py index 7d08d2963..9ee40ca3b 100644 --- a/tornado/log.py +++ b/tornado/log.py @@ -131,17 +131,19 @@ class LogFormatter(logging.Formatter): # it's worth it since the encoding errors that would otherwise # result are so useless (and tornado is fond of using utf8-encoded # byte strings whereever possible). - try: - message = _unicode(record.message) - except UnicodeDecodeError: - message = repr(record.message) + def safe_unicode(s): + try: + return _unicode(s) + except UnicodeDecodeError: + return repr(s) - formatted = prefix + " " + message + formatted = prefix + " " + safe_unicode(record.message) if record.exc_info: if not record.exc_text: record.exc_text = self.formatException(record.exc_info) if record.exc_text: - formatted = formatted.rstrip() + "\n" + record.exc_text + formatted = (formatted.rstrip() + "\n" + + safe_unicode(record.exc_text)) return formatted.replace("\n", "\n ") diff --git a/tornado/test/log_test.py b/tornado/test/log_test.py index 9fc290748..da9e3fc48 100644 --- a/tornado/test/log_test.py +++ b/tornado/test/log_test.py @@ -38,7 +38,9 @@ def ignore_bytes_warning(): class LogFormatterTest(unittest.TestCase): - LINE_RE = re.compile(b"\x01\\[E [0-9]{6} [0-9]{2}:[0-9]{2}:[0-9]{2} log_test:[0-9]+\\]\x02 (.*)") + # Matches the output of a single logging call (which may be multiple lines + # if a traceback was included, so we use the DOTALL option) + LINE_RE = re.compile(b"(?s)\x01\\[E [0-9]{6} [0-9]{2}:[0-9]{2}:[0-9]{2} log_test:[0-9]+\\]\x02 (.*)") def setUp(self): self.formatter = LogFormatter(color=False) @@ -103,6 +105,15 @@ class LogFormatterTest(unittest.TestCase): # copy of test_bytes_logging. self.assertEqual(self.get_output(), utf8(repr(utf8(u("\u00e9"))))) + def test_bytes_exception_logging(self): + try: + raise Exception(b'\xe9') + except Exception: + self.logger.exception('caught exception') + # This will be "Exception: \xe9" on python 2 or + # "Exception: b'\xe9'" on python 3. + self.assertRegexpMatches(self.get_output(), br'Exception.*\\xe9') + class UnicodeLogFormatterTest(LogFormatterTest): def make_handler(self, filename):