mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	[1.11.x] Fixed #28091 -- Re-raised original exception when closing cursor cleanup fails
This commit is contained in:
		
				
					committed by
					
						 Claude Paroz
						Claude Paroz
					
				
			
			
				
	
			
			
			
						parent
						
							5e2bbcd70c
						
					
				
				
					commit
					56746fb21f
				
			| @@ -874,7 +874,7 @@ class SQLCompiler(object): | ||||
|             cursor = self.connection.cursor() | ||||
|         try: | ||||
|             cursor.execute(sql, params) | ||||
|         except Exception: | ||||
|         except Exception as original_exception: | ||||
|             try: | ||||
|                 # Might fail for server-side cursors (e.g. connection closed) | ||||
|                 cursor.close() | ||||
| @@ -883,7 +883,7 @@ class SQLCompiler(object): | ||||
|                 # Python 2 doesn't chain exceptions. Remove this error | ||||
|                 # silencing when dropping Python 2 compatibility. | ||||
|                 pass | ||||
|             raise | ||||
|             raise original_exception | ||||
|  | ||||
|         if result_type == CURSOR: | ||||
|             # 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`). | ||||
|  | ||||
| * 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.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): | ||||
|         # fetchone, fetchmany, fetchall return strings as unicode objects #6254 | ||||
|         qn = connection.ops.quote_name | ||||
|   | ||||
		Reference in New Issue
	
	Block a user