1# Copyright 2014 Google Inc. All Rights Reserved. 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15"""Errors for the library. 16 17All exceptions defined by the library 18should be defined in this file. 19""" 20from __future__ import absolute_import 21 22__author__ = 'jcgregorio@google.com (Joe Gregorio)' 23 24import json 25 26# Oauth2client < 3 has the positional helper in 'util', >= 3 has it 27# in '_helpers'. 28try: 29 from oauth2client import util 30except ImportError: 31 from oauth2client import _helpers as util 32 33 34class Error(Exception): 35 """Base error for this module.""" 36 pass 37 38 39class HttpError(Error): 40 """HTTP data was invalid or unexpected.""" 41 42 @util.positional(3) 43 def __init__(self, resp, content, uri=None): 44 self.resp = resp 45 if not isinstance(content, bytes): 46 raise TypeError("HTTP content should be bytes") 47 self.content = content 48 self.uri = uri 49 50 def _get_reason(self): 51 """Calculate the reason for the error from the response content.""" 52 reason = self.resp.reason 53 try: 54 data = json.loads(self.content.decode('utf-8')) 55 reason = data['error']['message'] 56 except (ValueError, KeyError): 57 pass 58 if reason is None: 59 reason = '' 60 return reason 61 62 def __repr__(self): 63 if self.uri: 64 return '<HttpError %s when requesting %s returned "%s">' % ( 65 self.resp.status, self.uri, self._get_reason().strip()) 66 else: 67 return '<HttpError %s "%s">' % (self.resp.status, self._get_reason()) 68 69 __str__ = __repr__ 70 71 72class InvalidJsonError(Error): 73 """The JSON returned could not be parsed.""" 74 pass 75 76 77class UnknownFileType(Error): 78 """File type unknown or unexpected.""" 79 pass 80 81 82class UnknownLinkType(Error): 83 """Link type unknown or unexpected.""" 84 pass 85 86 87class UnknownApiNameOrVersion(Error): 88 """No API with that name and version exists.""" 89 pass 90 91 92class UnacceptableMimeTypeError(Error): 93 """That is an unacceptable mimetype for this operation.""" 94 pass 95 96 97class MediaUploadSizeError(Error): 98 """Media is larger than the method can accept.""" 99 pass 100 101 102class ResumableUploadError(HttpError): 103 """Error occured during resumable upload.""" 104 pass 105 106 107class InvalidChunkSizeError(Error): 108 """The given chunksize is not valid.""" 109 pass 110 111class InvalidNotificationError(Error): 112 """The channel Notification is invalid.""" 113 pass 114 115class BatchError(HttpError): 116 """Error occured during batch operations.""" 117 118 @util.positional(2) 119 def __init__(self, reason, resp=None, content=None): 120 self.resp = resp 121 self.content = content 122 self.reason = reason 123 124 def __repr__(self): 125 return '<BatchError %s "%s">' % (self.resp.status, self.reason) 126 127 __str__ = __repr__ 128 129 130class UnexpectedMethodError(Error): 131 """Exception raised by RequestMockBuilder on unexpected calls.""" 132 133 @util.positional(1) 134 def __init__(self, methodId=None): 135 """Constructor for an UnexpectedMethodError.""" 136 super(UnexpectedMethodError, self).__init__( 137 'Received unexpected call %s' % methodId) 138 139 140class UnexpectedBodyError(Error): 141 """Exception raised by RequestMockBuilder on unexpected bodies.""" 142 143 def __init__(self, expected, provided): 144 """Constructor for an UnexpectedMethodError.""" 145 super(UnexpectedBodyError, self).__init__( 146 'Expected: [%s] - Provided: [%s]' % (expected, provided)) 147