UnicodeDecodeError when logging an Exception in Python

logging, python, python-2.7, unicode

Solution

You are trying to interpolate a `unicode` object into a `str` template, triggering an implicit encoding.

Use a `unicode` template; `logging` can handle Unicode just fine:

logging.error(u'Error loading SCMTool for repository '
              '%s (ID %d): %s' % (repo.name, repo.id, e),
              exc_info=1)

Two additional tips:

You don't have to do the interpolation yourself; if you pass in the 3 elements to interpolate as separate arguments, `logging` will interpolate for you, but only if the message is actually going to be emitted.

If you use `logging.exception()` the message is logged at the `ERROR` level and `exc_info` is set for you; it gets you the same result but is more easily recognised when reading your code later. Either way, the exception is already included in that case, no need to include it again in the message.

As such, I'd use:

logging.exception(
    'Error loading SCMTool for repository %s (ID %d)',
    repo.name, repo.id)

Problem

I'm using Python 2.7.9. x32 on Win7 x64. When I'm logging an Exception containing Umlauts, I always receive `UnicodeDecodeError: 'ascii' codec can't decode byte 0xfc in position 39: ordinal not in range(128)` My example code is: ``` except Exception as e: logging.error('Error loading SCMTool for repository ' '%s (ID %d): %s' % (repo.name, repo.id, e), exc_info=1) ``` The Exception being logged is `WindowsError: [Error 267] Der Verzeichnisname ist ungültig`. The Problem is based on the "ungÜltig" umlaut. After removing the last `%s` and the `e` it works without a problem. This happens everytime an exception is logged, therefore changing every logger is no alternative. Does anyone have an idea how to make Exception return a unicode string globally?

Original source