~ubuntu-branches/ubuntu/saucy/python-cinderclient/saucy-proposed

« back to all changes in this revision

Viewing changes to cinderclient/exceptions.py

  • Committer: Package Import Robot
  • Author(s): Chuck Short
  • Date: 2012-06-27 13:32:14 UTC
  • Revision ID: package-import@ubuntu.com-20120627133214-n2gx1yxu97efvhg8
Tags: upstream-2012.2~f1~20120621.8
ImportĀ upstreamĀ versionĀ 2012.2~f1~20120621.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright 2010 Jacob Kaplan-Moss
 
2
"""
 
3
Exception definitions.
 
4
"""
 
5
 
 
6
 
 
7
class UnsupportedVersion(Exception):
 
8
    """Indicates that the user is trying to use an unsupported
 
9
    version of the API"""
 
10
    pass
 
11
 
 
12
 
 
13
class CommandError(Exception):
 
14
    pass
 
15
 
 
16
 
 
17
class AuthorizationFailure(Exception):
 
18
    pass
 
19
 
 
20
 
 
21
class NoUniqueMatch(Exception):
 
22
    pass
 
23
 
 
24
 
 
25
class NoTokenLookupException(Exception):
 
26
    """This form of authentication does not support looking up
 
27
       endpoints from an existing token."""
 
28
    pass
 
29
 
 
30
 
 
31
class EndpointNotFound(Exception):
 
32
    """Could not find Service or Region in Service Catalog."""
 
33
    pass
 
34
 
 
35
 
 
36
class AmbiguousEndpoints(Exception):
 
37
    """Found more than one matching endpoint in Service Catalog."""
 
38
    def __init__(self, endpoints=None):
 
39
        self.endpoints = endpoints
 
40
 
 
41
    def __str__(self):
 
42
        return "AmbiguousEndpoints: %s" % repr(self.endpoints)
 
43
 
 
44
 
 
45
class ClientException(Exception):
 
46
    """
 
47
    The base exception class for all exceptions this library raises.
 
48
    """
 
49
    def __init__(self, code, message=None, details=None, request_id=None):
 
50
        self.code = code
 
51
        self.message = message or self.__class__.message
 
52
        self.details = details
 
53
        self.request_id = request_id
 
54
 
 
55
    def __str__(self):
 
56
        formatted_string = "%s (HTTP %s)" % (self.message, self.code)
 
57
        if self.request_id:
 
58
            formatted_string += " (Request-ID: %s)" % self.request_id
 
59
 
 
60
        return formatted_string
 
61
 
 
62
 
 
63
class BadRequest(ClientException):
 
64
    """
 
65
    HTTP 400 - Bad request: you sent some malformed data.
 
66
    """
 
67
    http_status = 400
 
68
    message = "Bad request"
 
69
 
 
70
 
 
71
class Unauthorized(ClientException):
 
72
    """
 
73
    HTTP 401 - Unauthorized: bad credentials.
 
74
    """
 
75
    http_status = 401
 
76
    message = "Unauthorized"
 
77
 
 
78
 
 
79
class Forbidden(ClientException):
 
80
    """
 
81
    HTTP 403 - Forbidden: your credentials don't give you access to this
 
82
    resource.
 
83
    """
 
84
    http_status = 403
 
85
    message = "Forbidden"
 
86
 
 
87
 
 
88
class NotFound(ClientException):
 
89
    """
 
90
    HTTP 404 - Not found
 
91
    """
 
92
    http_status = 404
 
93
    message = "Not found"
 
94
 
 
95
 
 
96
class OverLimit(ClientException):
 
97
    """
 
98
    HTTP 413 - Over limit: you're over the API limits for this time period.
 
99
    """
 
100
    http_status = 413
 
101
    message = "Over limit"
 
102
 
 
103
 
 
104
# NotImplemented is a python keyword.
 
105
class HTTPNotImplemented(ClientException):
 
106
    """
 
107
    HTTP 501 - Not Implemented: the server does not support this operation.
 
108
    """
 
109
    http_status = 501
 
110
    message = "Not Implemented"
 
111
 
 
112
 
 
113
# In Python 2.4 Exception is old-style and thus doesn't have a __subclasses__()
 
114
# so we can do this:
 
115
#     _code_map = dict((c.http_status, c)
 
116
#                      for c in ClientException.__subclasses__())
 
117
#
 
118
# Instead, we have to hardcode it:
 
119
_code_map = dict((c.http_status, c) for c in [BadRequest, Unauthorized,
 
120
                                              Forbidden, NotFound,
 
121
                                              OverLimit, HTTPNotImplemented])
 
122
 
 
123
 
 
124
def from_response(response, body):
 
125
    """
 
126
    Return an instance of an ClientException or subclass
 
127
    based on an httplib2 response.
 
128
 
 
129
    Usage::
 
130
 
 
131
        resp, body = http.request(...)
 
132
        if resp.status != 200:
 
133
            raise exception_from_response(resp, body)
 
134
    """
 
135
    cls = _code_map.get(response.status, ClientException)
 
136
    request_id = response.get('x-compute-request-id')
 
137
    if body:
 
138
        message = "n/a"
 
139
        details = "n/a"
 
140
        if hasattr(body, 'keys'):
 
141
            error = body[body.keys()[0]]
 
142
            message = error.get('message', None)
 
143
            details = error.get('details', None)
 
144
        return cls(code=response.status, message=message, details=details,
 
145
                   request_id=request_id)
 
146
    else:
 
147
        return cls(code=response.status, request_id=request_id)