#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.

Reply via email to