From 6b6be692fcd102436c7abef1d7b3fa1d37ad4bdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Freitag?= Date: Fri, 13 Jan 2017 15:21:33 -0800 Subject: [PATCH] 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. --- django/db/models/sql/compiler.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py index 0778d38f4a..b197ab90cc 100644 --- a/django/db/models/sql/compiler.py +++ b/django/db/models/sql/compiler.py @@ -830,9 +830,14 @@ class SQLCompiler(object): try: cursor.execute(sql, params) except Exception: - with self.connection.wrap_database_errors: - # Closing a server-side cursor could yield an error + try: + # Might fail for server-side cursors (e.g. connection closed) cursor.close() + except Exception: + # Ignore clean up errors and raise the original error instead. + # Python 2 doesn't chain exceptions. Remove this error + # silencing when dropping Python 2 compatibility. + pass raise if result_type == CURSOR: