]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Handle non-ascii data in logged exceptions like in the main message.
authorBen Darnell <ben@bendarnell.com>
Sat, 9 Feb 2013 00:21:10 +0000 (19:21 -0500)
committerBen Darnell <ben@bendarnell.com>
Sat, 9 Feb 2013 00:21:10 +0000 (19:21 -0500)
Closes #675

tornado/log.py
tornado/test/log_test.py

index 7d08d296385b8dc1494b7c307fb69a034eaec005..9ee40ca3b6cbca47007d4b7acc7978e427239a59 100644 (file)
@@ -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    ")
 
 
index 9fc29074879076d50b09affcb9dc5c7ccb8f19e7..da9e3fc48da7b8d9d967f7048adabd9b1178ae5d 100644 (file)
@@ -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):