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() |             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 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user