Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(198)

Side by Side Diff: third_party/gsutil/boto/exception.py

Issue 12042069: Scripts to download files from google storage based on sha1 sums (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Removed gsutil/tests and gsutil/docs Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # Copyright (c) 2006-2010 Mitch Garnaat http://garnaat.org/
2 # Copyright (c) 2010, Eucalyptus Systems, Inc.
3 # All rights reserved.
4 #
5 # Permission is hereby granted, free of charge, to any person obtaining a
6 # copy of this software and associated documentation files (the
7 # "Software"), to deal in the Software without restriction, including
8 # without limitation the rights to use, copy, modify, merge, publish, dis-
9 # tribute, sublicense, and/or sell copies of the Software, and to permit
10 # persons to whom the Software is furnished to do so, subject to the fol-
11 # lowing conditions:
12 #
13 # The above copyright notice and this permission notice shall be included
14 # in all copies or substantial portions of the Software.
15 #
16 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
17 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
18 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
19 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 # IN THE SOFTWARE.
23
24 """
25 Exception classes - Subclassing allows you to check for specific errors
26 """
27 import base64
28 import xml.sax
29 from boto import handler
30 from boto.resultset import ResultSet
31
32
33 class BotoClientError(StandardError):
34 """
35 General Boto Client error (error accessing AWS)
36 """
37
38 def __init__(self, reason, *args):
39 StandardError.__init__(self, reason, *args)
40 self.reason = reason
41
42 def __repr__(self):
43 return 'BotoClientError: %s' % self.reason
44
45 def __str__(self):
46 return 'BotoClientError: %s' % self.reason
47
48 class SDBPersistenceError(StandardError):
49
50 pass
51
52 class StoragePermissionsError(BotoClientError):
53 """
54 Permissions error when accessing a bucket or key on a storage service.
55 """
56 pass
57
58 class S3PermissionsError(StoragePermissionsError):
59 """
60 Permissions error when accessing a bucket or key on S3.
61 """
62 pass
63
64 class GSPermissionsError(StoragePermissionsError):
65 """
66 Permissions error when accessing a bucket or key on GS.
67 """
68 pass
69
70 class BotoServerError(StandardError):
71
72 def __init__(self, status, reason, body=None, *args):
73 StandardError.__init__(self, status, reason, body, *args)
74 self.status = status
75 self.reason = reason
76 self.body = body or ''
77 self.request_id = None
78 self.error_code = None
79 self.error_message = None
80 self.box_usage = None
81
82 # Attempt to parse the error response. If body isn't present,
83 # then just ignore the error response.
84 if self.body:
85 try:
86 h = handler.XmlHandler(self, self)
87 xml.sax.parseString(self.body, h)
88 except (TypeError, xml.sax.SAXParseException), pe:
89 # Remove unparsable message body so we don't include garbage
90 # in exception. But first, save self.body in self.error_message
91 # because occasionally we get error messages from Eucalyptus
92 # that are just text strings that we want to preserve.
93 self.error_message = self.body
94 self.body = None
95
96 def __getattr__(self, name):
97 if name == 'message':
98 return self.error_message
99 if name == 'code':
100 return self.error_code
101 raise AttributeError
102
103 def __repr__(self):
104 return '%s: %s %s\n%s' % (self.__class__.__name__,
105 self.status, self.reason, self.body)
106
107 def __str__(self):
108 return '%s: %s %s\n%s' % (self.__class__.__name__,
109 self.status, self.reason, self.body)
110
111 def startElement(self, name, attrs, connection):
112 pass
113
114 def endElement(self, name, value, connection):
115 if name in ('RequestId', 'RequestID'):
116 self.request_id = value
117 elif name == 'Code':
118 self.error_code = value
119 elif name == 'Message':
120 self.error_message = value
121 elif name == 'BoxUsage':
122 self.box_usage = value
123 return None
124
125 def _cleanupParsedProperties(self):
126 self.request_id = None
127 self.error_code = None
128 self.error_message = None
129 self.box_usage = None
130
131 class ConsoleOutput:
132
133 def __init__(self, parent=None):
134 self.parent = parent
135 self.instance_id = None
136 self.timestamp = None
137 self.comment = None
138 self.output = None
139
140 def startElement(self, name, attrs, connection):
141 return None
142
143 def endElement(self, name, value, connection):
144 if name == 'instanceId':
145 self.instance_id = value
146 elif name == 'output':
147 self.output = base64.b64decode(value)
148 else:
149 setattr(self, name, value)
150
151 class StorageCreateError(BotoServerError):
152 """
153 Error creating a bucket or key on a storage service.
154 """
155 def __init__(self, status, reason, body=None):
156 self.bucket = None
157 BotoServerError.__init__(self, status, reason, body)
158
159 def endElement(self, name, value, connection):
160 if name == 'BucketName':
161 self.bucket = value
162 else:
163 return BotoServerError.endElement(self, name, value, connection)
164
165 class S3CreateError(StorageCreateError):
166 """
167 Error creating a bucket or key on S3.
168 """
169 pass
170
171 class GSCreateError(StorageCreateError):
172 """
173 Error creating a bucket or key on GS.
174 """
175 pass
176
177 class StorageCopyError(BotoServerError):
178 """
179 Error copying a key on a storage service.
180 """
181 pass
182
183 class S3CopyError(StorageCopyError):
184 """
185 Error copying a key on S3.
186 """
187 pass
188
189 class GSCopyError(StorageCopyError):
190 """
191 Error copying a key on GS.
192 """
193 pass
194
195 class SQSError(BotoServerError):
196 """
197 General Error on Simple Queue Service.
198 """
199 def __init__(self, status, reason, body=None):
200 self.detail = None
201 self.type = None
202 BotoServerError.__init__(self, status, reason, body)
203
204 def startElement(self, name, attrs, connection):
205 return BotoServerError.startElement(self, name, attrs, connection)
206
207 def endElement(self, name, value, connection):
208 if name == 'Detail':
209 self.detail = value
210 elif name == 'Type':
211 self.type = value
212 else:
213 return BotoServerError.endElement(self, name, value, connection)
214
215 def _cleanupParsedProperties(self):
216 BotoServerError._cleanupParsedProperties(self)
217 for p in ('detail', 'type'):
218 setattr(self, p, None)
219
220 class SQSDecodeError(BotoClientError):
221 """
222 Error when decoding an SQS message.
223 """
224 def __init__(self, reason, message):
225 BotoClientError.__init__(self, reason, message)
226 self.message = message
227
228 def __repr__(self):
229 return 'SQSDecodeError: %s' % self.reason
230
231 def __str__(self):
232 return 'SQSDecodeError: %s' % self.reason
233
234 class StorageResponseError(BotoServerError):
235 """
236 Error in response from a storage service.
237 """
238 def __init__(self, status, reason, body=None):
239 self.resource = None
240 BotoServerError.__init__(self, status, reason, body)
241
242 def startElement(self, name, attrs, connection):
243 return BotoServerError.startElement(self, name, attrs, connection)
244
245 def endElement(self, name, value, connection):
246 if name == 'Resource':
247 self.resource = value
248 else:
249 return BotoServerError.endElement(self, name, value, connection)
250
251 def _cleanupParsedProperties(self):
252 BotoServerError._cleanupParsedProperties(self)
253 for p in ('resource'):
254 setattr(self, p, None)
255
256 class S3ResponseError(StorageResponseError):
257 """
258 Error in response from S3.
259 """
260 pass
261
262 class GSResponseError(StorageResponseError):
263 """
264 Error in response from GS.
265 """
266 pass
267
268 class EC2ResponseError(BotoServerError):
269 """
270 Error in response from EC2.
271 """
272
273 def __init__(self, status, reason, body=None):
274 self.errors = None
275 self._errorResultSet = []
276 BotoServerError.__init__(self, status, reason, body)
277 self.errors = [ (e.error_code, e.error_message) \
278 for e in self._errorResultSet ]
279 if len(self.errors):
280 self.error_code, self.error_message = self.errors[0]
281
282 def startElement(self, name, attrs, connection):
283 if name == 'Errors':
284 self._errorResultSet = ResultSet([('Error', _EC2Error)])
285 return self._errorResultSet
286 else:
287 return None
288
289 def endElement(self, name, value, connection):
290 if name == 'RequestID':
291 self.request_id = value
292 else:
293 return None # don't call subclass here
294
295 def _cleanupParsedProperties(self):
296 BotoServerError._cleanupParsedProperties(self)
297 self._errorResultSet = []
298 for p in ('errors'):
299 setattr(self, p, None)
300
301 class DynamoDBResponseError(BotoServerError):
302 """
303 This exception expects the fully parsed and decoded JSON response
304 body to be passed as the body parameter.
305
306 :ivar status: The HTTP status code.
307 :ivar reason: The HTTP reason message.
308 :ivar body: The Python dict that represents the decoded JSON
309 response body.
310 :ivar error_message: The full description of the AWS error encountered.
311 :ivar error_code: A short string that identifies the AWS error
312 (e.g. ConditionalCheckFailedException)
313 """
314
315 def __init__(self, status, reason, body=None, *args):
316 self.status = status
317 self.reason = reason
318 self.body = body
319 if self.body:
320 self.error_message = self.body.get('message', None)
321 self.error_code = self.body.get('__type', None)
322 if self.error_code:
323 self.error_code = self.error_code.split('#')[-1]
324
325
326 class SWFResponseError(BotoServerError):
327 """
328 This exception expects the fully parsed and decoded JSON response
329 body to be passed as the body parameter.
330
331 :ivar status: The HTTP status code.
332 :ivar reason: The HTTP reason message.
333 :ivar body: The Python dict that represents the decoded JSON
334 response body.
335 :ivar error_message: The full description of the AWS error encountered.
336 :ivar error_code: A short string that identifies the AWS error
337 (e.g. ConditionalCheckFailedException)
338 """
339
340 def __init__(self, status, reason, body=None, *args):
341 self.status = status
342 self.reason = reason
343 self.body = body
344 if self.body:
345 self.error_message = self.body.get('message', None)
346 self.error_code = self.body.get('__type', None)
347 if self.error_code:
348 self.error_code = self.error_code.split('#')[-1]
349
350
351 class EmrResponseError(BotoServerError):
352 """
353 Error in response from EMR
354 """
355 pass
356
357 class _EC2Error:
358
359 def __init__(self, connection=None):
360 self.connection = connection
361 self.error_code = None
362 self.error_message = None
363
364 def startElement(self, name, attrs, connection):
365 return None
366
367 def endElement(self, name, value, connection):
368 if name == 'Code':
369 self.error_code = value
370 elif name == 'Message':
371 self.error_message = value
372 else:
373 return None
374
375 class SDBResponseError(BotoServerError):
376 """
377 Error in responses from SDB.
378 """
379 pass
380
381 class AWSConnectionError(BotoClientError):
382 """
383 General error connecting to Amazon Web Services.
384 """
385 pass
386
387 class StorageDataError(BotoClientError):
388 """
389 Error receiving data from a storage service.
390 """
391 pass
392
393 class S3DataError(StorageDataError):
394 """
395 Error receiving data from S3.
396 """
397 pass
398
399 class GSDataError(StorageDataError):
400 """
401 Error receiving data from GS.
402 """
403 pass
404
405 class InvalidUriError(Exception):
406 """Exception raised when URI is invalid."""
407
408 def __init__(self, message):
409 Exception.__init__(self, message)
410 self.message = message
411
412 class InvalidAclError(Exception):
413 """Exception raised when ACL XML is invalid."""
414
415 def __init__(self, message):
416 Exception.__init__(self, message)
417 self.message = message
418
419 class InvalidCorsError(Exception):
420 """Exception raised when CORS XML is invalid."""
421
422 def __init__(self, message):
423 Exception.__init__(self, message)
424 self.message = message
425
426 class NoAuthHandlerFound(Exception):
427 """Is raised when no auth handlers were found ready to authenticate."""
428 pass
429
430 class TooManyAuthHandlerReadyToAuthenticate(Exception):
431 """Is raised when there are more than one auth handler ready.
432
433 In normal situation there should only be one auth handler that is ready to
434 authenticate. In case where more than one auth handler is ready to
435 authenticate, we raise this exception, to prevent unpredictable behavior
436 when multiple auth handlers can handle a particular case and the one chosen
437 depends on the order they were checked.
438 """
439 pass
440
441 # Enum class for resumable upload failure disposition.
442 class ResumableTransferDisposition(object):
443 # START_OVER means an attempt to resume an existing transfer failed,
444 # and a new resumable upload should be attempted (without delay).
445 START_OVER = 'START_OVER'
446
447 # WAIT_BEFORE_RETRY means the resumable transfer failed but that it can
448 # be retried after a time delay within the current process.
449 WAIT_BEFORE_RETRY = 'WAIT_BEFORE_RETRY'
450
451 # ABORT_CUR_PROCESS means the resumable transfer failed and that
452 # delaying/retrying within the current process will not help. If
453 # resumable transfer included a state tracker file the upload can be
454 # retried again later, in another process (e.g., a later run of gsutil).
455 ABORT_CUR_PROCESS = 'ABORT_CUR_PROCESS'
456
457 # ABORT means the resumable transfer failed in a way that it does not
458 # make sense to continue in the current process, and further that the
459 # current tracker ID should not be preserved (in a tracker file if one
460 # was specified at resumable upload start time). If the user tries again
461 # later (e.g., a separate run of gsutil) it will get a new resumable
462 # upload ID.
463 ABORT = 'ABORT'
464
465 class ResumableUploadException(Exception):
466 """
467 Exception raised for various resumable upload problems.
468
469 self.disposition is of type ResumableTransferDisposition.
470 """
471
472 def __init__(self, message, disposition):
473 Exception.__init__(self, message, disposition)
474 self.message = message
475 self.disposition = disposition
476
477 def __repr__(self):
478 return 'ResumableUploadException("%s", %s)' % (
479 self.message, self.disposition)
480
481 class ResumableDownloadException(Exception):
482 """
483 Exception raised for various resumable download problems.
484
485 self.disposition is of type ResumableTransferDisposition.
486 """
487
488 def __init__(self, message, disposition):
489 Exception.__init__(self, message, disposition)
490 self.message = message
491 self.disposition = disposition
492
493 def __repr__(self):
494 return 'ResumableDownloadException("%s", %s)' % (
495 self.message, self.disposition)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698