Skip to content

Commit 6b6be69

Browse files
francoisfreitagtimgraham
authored andcommitted
Refs #16614 -- Prevented database errors from being masked by cursor close.
When an error occurred during the cursor.execute statement, the cursor is closed. This operation did not fail with client-side cursors. Now, with server-side cursors, the close operation might fail (example below). The original error should be raised, not the one raised by cursor.close(), this is only clean-up code. For example, one can attempt to create a named cursor for an invalid query. psycopg will raise an error about the invalid query and the server-side cursor will not be created on PostgreSQL. When the code attempts to cursor.close(), it asks psycopg to close a cursor that was not created. pyscopg raises a new error: psycopg2.OperationalError: cursor "_django_curs_140365867840512_20" does not exist.
1 parent 2e55790 commit 6b6be69

File tree

1 file changed

+7
-2
lines changed

1 file changed

+7
-2
lines changed

django/db/models/sql/compiler.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -830,9 +830,14 @@ def execute_sql(self, result_type=MULTI, chunked_fetch=False):
830830
try:
831831
cursor.execute(sql, params)
832832
except Exception:
833-
with self.connection.wrap_database_errors:
834-
# Closing a server-side cursor could yield an error
833+
try:
834+
# Might fail for server-side cursors (e.g. connection closed)
835835
cursor.close()
836+
except Exception:
837+
# Ignore clean up errors and raise the original error instead.
838+
# Python 2 doesn't chain exceptions. Remove this error
839+
# silencing when dropping Python 2 compatibility.
840+
pass
836841
raise
837842

838843
if result_type == CURSOR:

0 commit comments

Comments
 (0)