[1.11.x] Fixed #28091 -- Re-raised original exception when closing cursor cleanup fails
This commit is contained in:
parent
5e2bbcd70c
commit
56746fb21f
|
@ -874,7 +874,7 @@ class SQLCompiler(object):
|
||||||
cursor = self.connection.cursor()
|
cursor = self.connection.cursor()
|
||||||
try:
|
try:
|
||||||
cursor.execute(sql, params)
|
cursor.execute(sql, params)
|
||||||
except Exception:
|
except Exception as original_exception:
|
||||||
try:
|
try:
|
||||||
# Might fail for server-side cursors (e.g. connection closed)
|
# Might fail for server-side cursors (e.g. connection closed)
|
||||||
cursor.close()
|
cursor.close()
|
||||||
|
@ -883,7 +883,7 @@ class SQLCompiler(object):
|
||||||
# Python 2 doesn't chain exceptions. Remove this error
|
# Python 2 doesn't chain exceptions. Remove this error
|
||||||
# silencing when dropping Python 2 compatibility.
|
# silencing when dropping Python 2 compatibility.
|
||||||
pass
|
pass
|
||||||
raise
|
raise original_exception
|
||||||
|
|
||||||
if result_type == CURSOR:
|
if result_type == CURSOR:
|
||||||
# Caller didn't specify a result_type, so just give them back the
|
# Caller didn't specify a result_type, so just give them back the
|
||||||
|
|
|
@ -42,3 +42,7 @@ Bugfixes
|
||||||
``ModelAdmin.radio_fields`` with ``admin.HORIZONTAL`` (:ticket:`28059`).
|
``ModelAdmin.radio_fields`` with ``admin.HORIZONTAL`` (:ticket:`28059`).
|
||||||
|
|
||||||
* Fixed crash in ``BaseGeometryWidget.subwidgets()`` (:ticket:`28039`).
|
* Fixed crash in ``BaseGeometryWidget.subwidgets()`` (:ticket:`28039`).
|
||||||
|
|
||||||
|
* Re-raised the original exception when ``cursor.execute()`` fails and the
|
||||||
|
cleanup code ``cursor.close()`` fails as well, instead of raising the cleanup
|
||||||
|
code failure (:ticket:28091).
|
||||||
|
|
|
@ -682,6 +682,25 @@ class BackendTestCase(TransactionTestCase):
|
||||||
self.create_squares(args, 'pyformat', multiple=True)
|
self.create_squares(args, 'pyformat', multiple=True)
|
||||||
self.assertEqual(Square.objects.count(), 9)
|
self.assertEqual(Square.objects.count(), 9)
|
||||||
|
|
||||||
|
def test_cursor_close_failure_does_not_mask_original_exception(self):
|
||||||
|
persons = Person.objects.iterator()
|
||||||
|
|
||||||
|
def raise_original_exception(*args, **kwargs):
|
||||||
|
raise Exception('Real exception raised by the database on cursor.execute')
|
||||||
|
|
||||||
|
def raise_close_exception():
|
||||||
|
raise Exception(
|
||||||
|
'Error when attempting to close the cursor, this exception should not mask the original exception'
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_cursor = connection.chunked_cursor()
|
||||||
|
mock_cursor.execute = mock.MagicMock(side_effect=raise_original_exception)
|
||||||
|
mock_cursor.close = mock.MagicMock(side_effect=raise_close_exception)
|
||||||
|
|
||||||
|
with self.assertRaisesMessage(Exception, 'Real exception raised by the database on cursor.execute'):
|
||||||
|
with mock.patch('django.db.connection.create_cursor', return_value=mock_cursor):
|
||||||
|
list(persons)
|
||||||
|
|
||||||
def test_unicode_fetches(self):
|
def test_unicode_fetches(self):
|
||||||
# fetchone, fetchmany, fetchall return strings as unicode objects #6254
|
# fetchone, fetchmany, fetchall return strings as unicode objects #6254
|
||||||
qn = connection.ops.quote_name
|
qn = connection.ops.quote_name
|
||||||
|
|
Loading…
Reference in New Issue