Django DB backends hid information in database exceptions
|Reported by:||jamesh||Owned by:||nobody|
|Component:||Database layer (models, ORM)||Version:||master|
|Has patch:||yes||Needs documentation:||no|
|Needs tests:||no||Patch needs improvement:||no|
The Django DB backends replace the exceptions raised by the underlying adapter with standard ones from django.db.utils.
I understand the reason for doing this (provide standard exceptions that calling code can catch), but it can lose information provided by those exceptions. For example, the psycopg2 adapter exposes the SQL error code as a "code" attribute on exceptions, and this is lost.
Perhaps using the same strategy as Storm would help: rather than catching the adapter's exceptions and re-raising equivalent standard ones, it patches the adapter's exceptions so that they subclass from the standard ones. This could be done with a method like the following:
def install_exceptions(module): if not isinstance(module.DatabaseError, django.db.utils.DatabaseError): module.DatabaseError.__bases__ += (django.db.utils.DatabaseError,) if not isinstance(module.IntegrityError, django.db.utils.IntegrityError): module.IntegrityError.__bases__ += (django.db.utils.IntegrityError,)
Once the adapter's exceptions have been patched it would no longer be necessary to wrap the adapter's cursors, since the standard cursor would raise exceptions that could be caught by generic code.
Change History (6)
comment:1 Changed 2 years ago by jamesh
- Needs documentation unset
- Needs tests unset
- Patch needs improvement unset
comment:2 Changed 2 years ago by ptone
- Triage Stage changed from Unreviewed to Accepted
- Type changed from Uncategorized to Cleanup/optimization
comment:3 Changed 2 years ago by jamesh
- Triage Stage changed from Accepted to Unreviewed
- Type changed from Cleanup/optimization to Uncategorized