From fa95c0dc98ab85560e927aac8bba68f82235837c Mon Sep 17 00:00:00 2001 From: Josh Schneier Date: Thu, 22 Dec 2022 11:02:00 -0500 Subject: [PATCH] [s3] catch 404 when deleting objects --- storages/backends/s3boto3.py | 16 ++++++++++++---- tests/test_s3boto3.py | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/storages/backends/s3boto3.py b/storages/backends/s3boto3.py index c979c8640..7231750f4 100644 --- a/storages/backends/s3boto3.py +++ b/storages/backends/s3boto3.py @@ -446,16 +446,24 @@ def _save(self, name, content): return cleaned_name def delete(self, name): - name = self._normalize_name(clean_name(name)) - self.bucket.Object(name).delete() + try: + name = self._normalize_name(clean_name(name)) + self.bucket.Object(name).delete() + except ClientError as err: + if err.response['ResponseMetadata']['HTTPStatusCode'] == 404: + # Not an error to delete something that does not exist + return + + # Some other error was encountered. Re-raise it + raise def exists(self, name): name = self._normalize_name(clean_name(name)) try: self.connection.meta.client.head_object(Bucket=self.bucket_name, Key=name) return True - except ClientError as error: - if error.response['ResponseMetadata']['HTTPStatusCode'] == 404: + except ClientError as err: + if err.response['ResponseMetadata']['HTTPStatusCode'] == 404: return False # Some other error was encountered. Re-raise it. diff --git a/tests/test_s3boto3.py b/tests/test_s3boto3.py index ed05fd311..df236af09 100644 --- a/tests/test_s3boto3.py +++ b/tests/test_s3boto3.py @@ -485,6 +485,24 @@ def test_storage_delete(self): self.storage.bucket.Object.assert_called_with('path/to/file.txt') self.storage.bucket.Object.return_value.delete.assert_called_with() + def test_storage_delete_does_not_exist(self): + self.storage.bucket.Object('file.txt').delete.side_effect = ClientError( + {'Error': {}, 'ResponseMetadata': {'HTTPStatusCode': 404}}, + 'DeleteObject', + ) + self.storage.delete('file.txt') + # No problem + + def test_storage_delete_other_error_reraise(self): + self.storage.bucket.Object('file.txt').delete.side_effect = ClientError( + {'Error': {}, 'ResponseMetadata': {'HTTPStatusCode': 403}}, + 'DeleteObject', + ) + with self.assertRaises(ClientError) as cm: + self.storage.delete('file.txt') + + self.assertEqual(cm.exception.response['ResponseMetadata']['HTTPStatusCode'], 403) + def test_storage_listdir_base(self): # Files: # some/path/1.txt