diff options
author | Brian Waldon <bcwaldon@gmail.com> | 2012-07-12 18:30:54 -0700 |
---|---|---|
committer | Brian Waldon <bcwaldon@gmail.com> | 2012-07-13 18:38:15 -0700 |
commit | 53acf1a0ca70c900267286a249e476fffe078a9f (patch) | |
tree | fe9d1c8db6b2767e2a0479abc154e42003ca326d /glanceclient/exc.py | |
parent | 49bc6f94f29ee7286601be0451ab3dafc82a0750 (diff) | |
download | python-glanceclient-53acf1a0ca70c900267286a249e476fffe078a9f.tar.gz |
Establish the supported importable interface
* Consumers of this client should not depend on being able to import
any module other than glanceclient and glanceclient
* The only attributs of the glanceclient module are Client
and __version__
* The attributes of the glanceclient.exc modules have yet to be
locked down
* glanceclient.common.exceptions was replaced with a placeholder
module until consumers of it are updated
Change-Id: Iea9648cd06906d65764987c1f2ee5a88ebeee748
Diffstat (limited to 'glanceclient/exc.py')
-rw-r--r-- | glanceclient/exc.py | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/glanceclient/exc.py b/glanceclient/exc.py new file mode 100644 index 0000000..d88f94b --- /dev/null +++ b/glanceclient/exc.py @@ -0,0 +1,131 @@ +""" +Exception definitions. +""" + + +class CommandError(Exception): + pass + + +class NoTokenLookupException(Exception): + """This form of authentication does not support looking up + endpoints from an existing token.""" + pass + + +class EndpointNotFound(Exception): + """Could not find Service or Region in Service Catalog.""" + pass + + +class SchemaNotFound(KeyError): + """Could not find schema""" + pass + + +class ClientException(Exception): + """ + The base exception class for all exceptions this library raises. + """ + def __init__(self, code, message=None, details=None): + self.code = code + self.message = message or self.__class__.message + self.details = details + + def __str__(self): + return "%s (HTTP %s)" % (self.message, self.code) + + +class BadRequest(ClientException): + """ + HTTP 400 - Bad request: you sent some malformed data. + """ + http_status = 400 + message = "Bad request" + + +class Unauthorized(ClientException): + """ + HTTP 401 - Unauthorized: bad credentials. + """ + http_status = 401 + message = "Unauthorized" + + +class Forbidden(ClientException): + """ + HTTP 403 - Forbidden: your credentials don't give you access to this + resource. + """ + http_status = 403 + message = "Forbidden" + + +class NotFound(ClientException): + """ + HTTP 404 - Not found + """ + http_status = 404 + message = "Not found" + + +class Conflict(ClientException): + """ + HTTP 409 - Conflict + """ + http_status = 409 + message = "Conflict" + + +class OverLimit(ClientException): + """ + HTTP 413 - Over limit: you're over the API limits for this time period. + """ + http_status = 413 + message = "Over limit" + + +# NotImplemented is a python keyword. +class HTTPNotImplemented(ClientException): + """ + HTTP 501 - Not Implemented: the server does not support this operation. + """ + http_status = 501 + message = "Not Implemented" + + +# In Python 2.4 Exception is old-style and thus doesn't have a __subclasses__() +# so we can do this: +# _code_map = dict((c.http_status, c) +# for c in ClientException.__subclasses__()) +# +# Instead, we have to hardcode it: +_code_map = dict((c.http_status, c) for c in [BadRequest, Unauthorized, + Forbidden, NotFound, OverLimit, HTTPNotImplemented]) + + +def from_response(response, body): + """ + Return an instance of an ClientException or subclass + based on an httplib2 response. + + Usage:: + + resp, body = http.request(...) + if resp.status != 200: + raise exception_from_response(resp, body) + """ + cls = _code_map.get(response.status, ClientException) + if body: + if hasattr(body, 'keys'): + error = body[body.keys()[0]] + message = error.get('message', None) + details = error.get('details', None) + else: + # If we didn't get back a properly formed error message we + # probably couldn't communicate with Keystone at all. + message = "Unable to communicate with image service: %s." % body + details = None + return cls(code=response.status, message=message, details=details) + else: + return cls(code=response.status) |