From 1460a5a3c7601a2f0ebb057c80ec71835adc509b Mon Sep 17 00:00:00 2001 From: Konstantinos Koukopoulos Date: Tue, 10 Feb 2015 15:33:18 +0200 Subject: [PATCH] refactor S3 exceptions to inherit from RESTError --- moto/s3/exceptions.py | 37 ++++++++++++++++++++++++++++++++++--- moto/s3/models.py | 4 ++-- moto/s3/responses.py | 41 ++++++++++------------------------------- 3 files changed, 46 insertions(+), 36 deletions(-) diff --git a/moto/s3/exceptions.py b/moto/s3/exceptions.py index 52d8faced..3997b0afe 100644 --- a/moto/s3/exceptions.py +++ b/moto/s3/exceptions.py @@ -1,9 +1,40 @@ from __future__ import unicode_literals +from moto.core.exceptions import RESTError -class BucketAlreadyExists(Exception): +ERROR_WITH_BUCKET_NAME = """{% extends 'error' %} +{% block extra %}{{ bucket }}{% endblock %} +""" + + +class S3ClientError(RESTError): pass -class MissingBucket(Exception): - pass +class BucketError(S3ClientError): + def __init__(self, *args, **kwargs): + kwargs.setdefault('template', 'bucket_error') + self.templates['bucket_error'] = ERROR_WITH_BUCKET_NAME + super(BucketError, self).__init__(*args, **kwargs) + + +class BucketAlreadyExists(BucketError): + code = 409 + + def __init__(self, *args, **kwargs): + super(BucketAlreadyExists, self).__init__( + "BucketAlreadyExists", + ("The requested bucket name is not available. The bucket " + "namespace is shared by all users of the system. Please " + "select a different name and try again"), + *args, **kwargs) + + +class MissingBucket(BucketError): + code = 404 + + def __init__(self, *args, **kwargs): + super(MissingBucket, self).__init__( + "NoSuchBucket", + "The specified bucket does not exist", + *args, **kwargs) diff --git a/moto/s3/models.py b/moto/s3/models.py index 2a78a8003..0f88f76d4 100644 --- a/moto/s3/models.py +++ b/moto/s3/models.py @@ -191,7 +191,7 @@ class S3Backend(BaseBackend): def create_bucket(self, bucket_name, region_name): if bucket_name in self.buckets: - raise BucketAlreadyExists() + raise BucketAlreadyExists(bucket=bucket_name) new_bucket = FakeBucket(name=bucket_name, region_name=region_name) self.buckets[bucket_name] = new_bucket return new_bucket @@ -203,7 +203,7 @@ class S3Backend(BaseBackend): try: return self.buckets[bucket_name] except KeyError: - raise MissingBucket() + raise MissingBucket(bucket=bucket_name) def delete_bucket(self, bucket_name): bucket = self.get_bucket(bucket_name) diff --git a/moto/s3/responses.py b/moto/s3/responses.py index 750bf68ba..d9ef63012 100644 --- a/moto/s3/responses.py +++ b/moto/s3/responses.py @@ -7,7 +7,7 @@ from six.moves.urllib.parse import parse_qs, urlparse from moto.core.responses import _TemplateEnvironmentMixin -from .exceptions import BucketAlreadyExists, MissingBucket +from .exceptions import BucketAlreadyExists, S3ClientError from .models import s3_backend from .utils import bucket_name_from_url, metadata_from_headers from xml.dom import minidom @@ -35,8 +35,8 @@ class ResponseObject(_TemplateEnvironmentMixin): def bucket_response(self, request, full_url, headers): try: response = self._bucket_response(request, full_url, headers) - except MissingBucket: - return 404, headers, "" + except S3ClientError as s3error: + response = s3error.code, headers, s3error.description if isinstance(response, six.string_types): return 200, headers, response.encode("utf-8") @@ -72,12 +72,8 @@ class ResponseObject(_TemplateEnvironmentMixin): raise NotImplementedError("Method {0} has not been impelemented in the S3 backend yet".format(method)) def _bucket_response_head(self, bucket_name, headers): - try: - self.backend.get_bucket(bucket_name) - except MissingBucket: - return 404, headers, "" - else: - return 200, headers, "" + self.backend.get_bucket(bucket_name) + return 200, headers, "" def _bucket_response_get(self, bucket_name, querystring, headers): if 'uploads' in querystring: @@ -127,11 +123,7 @@ class ResponseObject(_TemplateEnvironmentMixin): is_truncated='false', ) - try: - bucket = self.backend.get_bucket(bucket_name) - except MissingBucket: - return 404, headers, "" - + bucket = self.backend.get_bucket(bucket_name) prefix = querystring.get('prefix', [None])[0] delimiter = querystring.get('delimiter', [None])[0] result_keys, result_folders = self.backend.prefix_query(bucket, prefix, delimiter) @@ -161,17 +153,12 @@ class ResponseObject(_TemplateEnvironmentMixin): # us-east-1 has different behavior new_bucket = self.backend.get_bucket(bucket_name) else: - return 409, headers, "" + raise template = self.response_template(S3_BUCKET_CREATE_RESPONSE) return 200, headers, template.render(bucket=new_bucket) def _bucket_response_delete(self, bucket_name, headers): - try: - removed_bucket = self.backend.delete_bucket(bucket_name) - except MissingBucket: - # Non-existant bucket - template = self.response_template(S3_DELETE_NON_EXISTING_BUCKET) - return 404, headers, template.render(bucket_name=bucket_name) + removed_bucket = self.backend.delete_bucket(bucket_name) if removed_bucket: # Bucket exists @@ -231,8 +218,8 @@ class ResponseObject(_TemplateEnvironmentMixin): def key_response(self, request, full_url, headers): try: response = self._key_response(request, full_url, headers) - except MissingBucket: - return 404, headers, "" + except S3ClientError as s3error: + response = s3error.code, headers, s3error.description if isinstance(response, six.string_types): return 200, headers, response @@ -461,14 +448,6 @@ S3_DELETE_BUCKET_SUCCESS = """ -NoSuchBucket -The specified bucket does not exist -{{ bucket_name }} -asdfasdfsadf -asfasdfsfsafasdf -""" - S3_DELETE_BUCKET_WITH_ITEMS_ERROR = """ BucketNotEmpty The bucket you tried to delete is not empty