Skip to content

Commit

Permalink
PYTHON-1682 UTF-8 encode unicode error messages on Python 2
Browse files Browse the repository at this point in the history
  • Loading branch information
ShaneHarvey committed Nov 14, 2018
1 parent 341b2b5 commit e711408
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 0 deletions.
8 changes: 8 additions & 0 deletions pymongo/errors.py
Expand Up @@ -14,6 +14,8 @@

"""Exceptions raised by PyMongo."""

import sys

from bson.errors import *

try:
Expand All @@ -26,6 +28,7 @@ class PyMongoError(Exception):
"""Base class for all PyMongo exceptions."""
def __init__(self, message='', error_labels=None):
super(PyMongoError, self).__init__(message)
self._message = message
self._error_labels = set(error_labels or [])

def has_error_label(self, label):
Expand All @@ -43,6 +46,11 @@ def _remove_error_label(self, label):
"""Remove the given label from this error."""
self._error_labels.remove(label)

def __str__(self):
if sys.version_info[0] == 2 and isinstance(self._message, unicode):

This comment has been minimized.

Copy link
@Kami

Kami Aug 16, 2019

Just a heads up - this breaks mongoengine when an error message contains non-ascii data and default encoding used by Python is not utf8.

See MongoEngine/mongoengine#1428 (comment) for details.

I'm looking into a fix on the mongoengine level although this could affect other code which pymongo which doesn't use utf8 encoding by default (it's fairly common for Python encoding to still default to ascii).

This comment has been minimized.

Copy link
@Kami

Kami Aug 16, 2019

Just a heads up, here is a fix / change I proposed for mongoengine - MongoEngine/mongoengine#2147.

This comment has been minimized.

Copy link
@ShaneHarvey

ShaneHarvey Aug 16, 2019

Author Member

Thanks @Kami I've opened https://jira.mongodb.org/browse/PYTHON-1966 to fix this.

return self._message.encode('utf-8', errors='replace')
return str(self._message)


class ProtocolError(PyMongoError):
"""Raised for failures related to the wire protocol."""
Expand Down
15 changes: 15 additions & 0 deletions test/test_collection.py
Expand Up @@ -1316,6 +1316,21 @@ def test_write_error_text_handling(self):
db.test.insert_many,
[{"text": text}])

def test_write_error_unicode(self):
coll = self.db.test
self.addCleanup(coll.drop)

coll.create_index('a', unique=True)
coll.insert_one({'a': u'unicode \U0001f40d'})
with self.assertRaisesRegex(
DuplicateKeyError,
'E11000 duplicate key error') as ctx:
coll.insert_one({'a': u'unicode \U0001f40d'})

# Once more for good measure.
self.assertIn('E11000 duplicate key error',
str(ctx.exception))

def test_wtimeout(self):
# Ensure setting wtimeout doesn't disable write concern altogether.
# See SERVER-12596.
Expand Down

0 comments on commit e711408

Please sign in to comment.