Skip to content

Commit

Permalink
[s3] Re-raise non-404 errors in .exists() (jschneier#1085)
Browse files Browse the repository at this point in the history
  • Loading branch information
jschneier committed Oct 30, 2021
1 parent 8942ff2 commit 10be72f
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 9 deletions.
11 changes: 4 additions & 7 deletions storages/backends/s3boto3.py
Original file line number Diff line number Diff line change
Expand Up @@ -469,18 +469,15 @@ def exists(self, name):
self.connection.meta.client.head_object(Bucket=self.bucket_name, Key=name)
return True
except ClientError as error:
if error.response.get('Error', {}).get('Code') == '404':
if error.response['ResponseMetadata']['HTTPStatusCode'] == 404:
return False

# Some other error was encountered. As `get_available_name` calls this,
# we have to assume the filename is unavailable. If we return true due to some
# other error, we'd overwrite a file.
return True
# Some other error was encountered. Re-raise it.
raise

def listdir(self, name):
path = self._normalize_name(self._clean_name(name))
# The path needs to end with a slash, but if the root is empty, leave
# it.
# The path needs to end with a slash, but if the root is empty, leave it.
if path and not path.endswith('/'):
path += '/'

Expand Down
14 changes: 12 additions & 2 deletions tests/test_s3boto3.py
Original file line number Diff line number Diff line change
Expand Up @@ -488,15 +488,25 @@ def test_storage_exists(self):

def test_storage_exists_false(self):
self.storage.connection.meta.client.head_object.side_effect = ClientError(
{'Error': {'Code': '404', 'Message': 'Not Found'}},
{'Error': {}, 'ResponseMetadata': {'HTTPStatusCode': 404}},
'HeadObject',
)
self.assertFalse(self.storage.exists("file.txt"))
self.assertFalse(self.storage.exists('file.txt'))
self.storage.connection.meta.client.head_object.assert_called_with(
Bucket=self.storage.bucket_name,
Key='file.txt',
)

def test_storage_exists_other_error_reraise(self):
self.storage.connection.meta.client.head_object.side_effect = ClientError(
{'Error': {}, 'ResponseMetadata': {'HTTPStatusCode': 403}},
'HeadObject',
)
with self.assertRaises(ClientError) as cm:
self.storage.exists('file.txt')

self.assertEqual(cm.exception.response['ResponseMetadata']['HTTPStatusCode'], 403)

def test_storage_delete(self):
self.storage.delete("path/to/file.txt")
self.storage.bucket.Object.assert_called_with('path/to/file.txt')
Expand Down

0 comments on commit 10be72f

Please sign in to comment.