Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UnicodeDecodeError when logging an Exception in Python

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?

like image 282
Seega Avatar asked Feb 20 '15 10:02

Seega


1 Answers

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)
like image 200
Martijn Pieters Avatar answered Nov 15 '22 07:11

Martijn Pieters