#15901: Django should wrap all PEP 249 exceptions in db.utils
-------------------------------------+-------------------------------------
Reporter: xiaket | Owner: nobody
Type: New feature | Status: new
Component: Database layer | Version: 1.3
(models, ORM) | Resolution:
Severity: Normal | Triage Stage: Accepted
Keywords: | Needs documentation: 0
Has patch: 1 | Patch needs improvement: 0
Needs tests: 0 | UI/UX: 0
Easy pickings: 0 |
-------------------------------------+-------------------------------------
Comment (by gcbirzan):
Replying to [comment:9 jamesh]:
> Attaching my patch from the duplicate ticket so it doesn't get lost.
Has anyone else given the patch a test to see if it covers their use
cases?
That is an absolutely terrible way of doing things. Monkey patching should
be avoided, and this is a perfect example of when it would be a bad idea
to do so. Monkey patching the backend exceptions would mean that there's
no way to distinguish between exceptions raised by the django wrapper and
by the backend itself (by backend here I mean psycopg2, oursql, sqlite3,
whathaveyou).
There are two other solutions to this. The first is the established way of
handling this, passing a value to the outer exception:
{{{
try:
do_stuff()
except Database.DatabaseError as e:
raise util.DatabaseError, e, sys.exc_info()[2]
}}}
This preserves the message, e.message will still contain the original
message, while e.args[0] contains the original exception. A variation
thereof can be using an attribute on e for the inner exception. Testing
the inner exception would be awkward, but it would be possible.
Another way, albeit a bit unconventional, would be:
{{{
try:
do_stuff()
except Database.DatabaseError as e:
raise type('DatabaseError', (Database.DatabaseError,
util.DatabaseError), {}), e.args, sys.exc_info()[2]
}}}
This would allow you to do catch both types of the exception, just through
the except class as e syntax, but it would still be awkward for testing if
an exception was raised by django or not (you'd have to do except
backend.DatabaseError as e: first, and only then do util.DatabaseError).
The latter also has the benefit of not breaking most of the current
implementations, whereas the first one might if someone relies on e.args
(though, as mentioned, that can be kept intact, and the inner exception
can be put in an attribute).
I also think that this bug should get back to design decision needed, but
I'll leave that up the actual developers of django.
--
Ticket URL: <https://code.djangoproject.com/ticket/15901#comment:10>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.