-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Change exception wrapping to use repr instead of str #419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Huh ... so |
Hi @ionelmc, It would be interesting to add the repr information in python 2's exception. Perhaps we could add both the str() and repr()? In Python 3 I think we should look into relying on the built-in exception Are you able to diagnose the cryptic InvalidBSON error with your change? You'll probably also want to change the pure Python version of the code too: https://github.com/mongodb/mongo-python-driver/blob/3.8.0/bson/__init__.py#L443-L446 |
Sounds like good compromise, repr on 2, str+context on 3. |
So I looked a bit at the code - it's a bit annoying to change, I don't get why it was written like that. How exactly does calling _error clears the error state? |
@ionelmc Exception handling code is not pretty in C land :). I suggest holding off on making the C changes until we've found a suitable API in pure python. I talked a bit about this problem with my co-worker @prashantmital and we think that it may make more sense to add the original exception as a property of the re-raised InvalidBSON exception, something like this: class InvalidBSON(BSONError):
"""Raised when trying to create a BSON object from invalid data.
"""
def __init__(self, msg='', cause=None):
super(InvalidBSON, self).__init__(msg)
self._msg = msg
self._cause = cause
@property
def cause(self):
"""The exception which caused this InvalidBSON error or None.
"""
return self._cause We would provide the import bson
from bson.errors import InvalidBSON
try:
bson.BSON('\x0e\x00\x00\x00\x10_\xFFd\x00\x01\x00\x00\x00\x00').decode()
except InvalidBSON as exc:
# InvalidBSON("'utf8' codec can't decode byte 0xff in position 1: invalid start byte",)
print(repr(exc))
# UnicodeDecodeError('utf8', '_\xffd', 1, 2, 'invalid start byte')
print(repr(exc.cause)) What do you think about this approach? I'd still like to get to the bottom the cryptic |
This doesn't seem to be a problem in pure Python 3 since we have exception chaining:
It might be interesting to fix up our C extensions to also do exception chaining. @ionelmc would that solve your problem? |
This project doesn't use python3 yet. I have uncovered the real cause now, it's a Considering that I think the best way would be avoiding rewrapping when MemoryError is seen (in addition to using repr instead of str on py2). Can you explain why calling _error clears the error state? |
I suspect that Anyway ... it turns out this get error object and import on demand thing was added in b738a6f - I don't consider this a good change. |
Importing objects on demand like that is necessary to deal with Python subinterpreter issues that come up with packages like mod_wsgi. For details (and related code) see 2483775. |
A simple change to resolve this might be to check if the original exception provides a non-empty error string and fall back to the original exception name as the error string in that case. |
@ionelmc what do you think of my last proposal? If it sounds reasonable would you be willing to update this PR? |
I don't think looking inside the exception is a good idea. It would open another can of worms. |
(Actual) tracking ticket: PYTHON-2047 |
Thanks for bringing this issue to our attention! We're going to go with a different approach to fixing this problem as described in: https://jira.mongodb.org/browse/PYTHON-2047 Instead of always calling repr(), we're going to fallback to repr() only when str() results in an empty string. |
I have an app that makes heavy use of pymongo. However once in a while I get a "InvalidBSON('',)" exception. I haven't been able to track the original exception because pymongo discards useful information when wrapping exceptions.