app/django/utils/encoding.py
changeset 323 ff1a9aa48cfd
parent 54 03e267d67478
--- a/app/django/utils/encoding.py	Tue Oct 14 12:36:55 2008 +0000
+++ b/app/django/utils/encoding.py	Tue Oct 14 16:00:59 2008 +0000
@@ -1,9 +1,7 @@
 import types
 import urllib
 import datetime
-
 from django.utils.functional import Promise
-from django.utils.safestring import SafeData, mark_safe
 
 class DjangoUnicodeDecodeError(UnicodeDecodeError):
     def __init__(self, obj, *args):
@@ -50,7 +48,19 @@
             if hasattr(s, '__unicode__'):
                 s = unicode(s)
             else:
-                s = unicode(str(s), encoding, errors)
+                try:
+                    s = unicode(str(s), encoding, errors)
+                except UnicodeEncodeError:
+                    if not isinstance(s, Exception):
+                        raise
+                    # If we get to here, the caller has passed in an Exception
+                    # subclass populated with non-ASCII data without special
+                    # handling to display as a string. We need to handle this
+                    # without raising a further exception. We do an
+                    # approximation to what the Exception's standard str()
+                    # output should be.
+                    s = ' '.join([force_unicode(arg, encoding, strings_only,
+                            errors) for arg in s])
         elif not isinstance(s, unicode):
             # Note: We use .decode() here, instead of unicode(s, encoding,
             # errors), so that if s is a SafeString, it ends up being a
@@ -74,6 +84,12 @@
         try:
             return str(s)
         except UnicodeEncodeError:
+            if isinstance(s, Exception):
+                # An Exception subclass containing non-ASCII data that doesn't
+                # know how to print itself properly. We shouldn't raise a
+                # further exception.
+                return ' '.join([smart_str(arg, encoding, strings_only,
+                        errors) for arg in s])
             return unicode(s).encode(encoding, errors)
     elif isinstance(s, unicode):
         return s.encode(encoding, errors)