Opened 7 months ago

Last modified 7 months ago

#29257 new Bug

If creation of a db cursor fails, the resulting traceback is misleading

Reported by: Jerome Leclanche Owned by: nobody
Component: Database layer (models, ORM) Version: 2.0
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: yes Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

When a schema is out of sync (eg. running tests for a project where a model has fields not present in the migration).

The creation of a cursor involves a sql query which includes all of the field names. Creating that cursor will fail.
However, the exception is currently caught by a try/except which always attempts to *close* the cursor. Closing the cursor is not try/excepted, which results in that particular query failing and a traceback that looks like "ERROR: cursor "_django_curs_140260213699904_6" does not exist".

Patch:

commit 7c7a1f53acbf7d94f0a9b360f973711a7c9fbfbd (HEAD -> refs/heads/master)
Author: Jerome Leclanche <jerome@leclan.ch>
Date:   Tue Mar 20 09:57:26 2018 +0200

    Raise outer exception when failing to close a cursor after an error

diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
index 1fdbd156b6..f96be3c4ea 100644
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -1051,10 +1051,15 @@ class SQLCompiler:
             cursor = self.connection.cursor()
         try:
             cursor.execute(sql, params)
-        except Exception:
+        except Exception as e:
             # Might fail for server-side cursors (e.g. connection closed)
-            cursor.close()
-            raise
+            try:
+                cursor.close()
+            except Exception:
+                # If we got an error creating the cursor, then closing it
+                # will always fail. Raise the outer exception instead of the
+                # obscure "cursor _django_curs_xxxx does not exist".
+                raise e from None
 
         if result_type == CURSOR:
             # Give the caller the cursor to process and close.

Change History (1)

comment:1 Changed 7 months ago by Tim Graham

Needs tests: set
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug
Note: See TracTickets for help on using tickets.
Back to Top