projectal.errors
1from requests import HTTPError 2 3try: 4 from simplejson.errors import JSONDecodeError 5except ImportError: 6 from json.decoder import JSONDecodeError 7 8 9class LoginException(Exception): 10 """Failed to log in with the credentials provided.""" 11 pass 12 13class UnsupportedException(Exception): 14 """The API endpoint is not available for this entity.""" 15 pass 16 17class ProjectalException(Exception): 18 """ 19 The API request failed. This exception will extract the specific 20 error from the Projectal response if it can find one. To assist 21 in debugging, the response object is attached to the exception 22 which you may inspect for more precise details. 23 24 In case of failure of a bulk operation, only the error clue for 25 the first failure is shown. A counter is included to show how 26 many failed (i.e.: 1 of 25). 27 """ 28 def __init__(self, response, reason_message=None): 29 """ 30 `response`: the response object 31 32 `reason_message`: if provided, will use this message as the cause 33 of failure instead of assuming it was a misuse of the API. 34 """ 35 self.response = response 36 self.url = response.url 37 self.body = response.request.body 38 self.json = None 39 self.message = None 40 code = response.status_code 41 42 try: 43 self.json = response.json() 44 except JSONDecodeError: 45 pass 46 47 # Did we get a 200 response but (manually) raised anyway? The consumer 48 # method considered this an error. If it did, it MUST tell us why in 49 # the message parameter. We pass this message on to the user. 50 if code != 207: 51 try: 52 response.raise_for_status() 53 if reason_message: 54 self.message = reason_message 55 else: 56 self.message = 'Unexpected response (API client error)' 57 except HTTPError: 58 pass 59 60 if code == 400 and not self.json: 61 self.message = 'Client request error' 62 if code == 500: 63 self.message = 'Internal server error' 64 if self.json and (code == 400 or code == 422 or code == 207): 65 if self.json.get('feedbackList', False): 66 self.feedback = [f for f in self.json.get('feedbackList', [])] or None 67 clue = [f['clue'] for f in self.json['feedbackList'] if f['clue'] not in ['OK', 'Created']] 68 hint = [f['hint'].replace('\'', '\"') for f in self.json['feedbackList'] if f['clue'] not in ['OK', 'Created']] 69 if len(clue) == 1: 70 clue_part = " - Clue: {} ({})".format(clue[0], hint[0]) 71 else: 72 clue_part = " - Clue 1 of {}: {} ({})".format(len(clue), clue[0], hint[0]) 73 else: 74 # No feedback list, but clue in top-leel of dict 75 clue = self.json['jobClue']['clue'] 76 hint = self.json['jobClue']['hint'].replace('\'', '\"') 77 clue_part = ' - Clue: {} ({})'.format(clue, hint) 78 self.message = self.json['status'] + clue_part 79 80 if not self.message: 81 self.message = "Request error: {}".format(code) 82 super().__init__(self.message) 83 84 85class ProjectalVersionException(Exception): 86 """ 87 The Projectal server version is incompatible with the version 88 of this library. 89 """ 90 pass 91 92 93class UsageException(Exception): 94 """ 95 The library was used incorrectly and we were able to detect it 96 before making a request. 97 """ 98 pass
Failed to log in with the credentials provided.
Inherited Members
- builtins.Exception
- Exception
- builtins.BaseException
- with_traceback
14class UnsupportedException(Exception): 15 """The API endpoint is not available for this entity.""" 16 pass
The API endpoint is not available for this entity.
Inherited Members
- builtins.Exception
- Exception
- builtins.BaseException
- with_traceback
18class ProjectalException(Exception): 19 """ 20 The API request failed. This exception will extract the specific 21 error from the Projectal response if it can find one. To assist 22 in debugging, the response object is attached to the exception 23 which you may inspect for more precise details. 24 25 In case of failure of a bulk operation, only the error clue for 26 the first failure is shown. A counter is included to show how 27 many failed (i.e.: 1 of 25). 28 """ 29 def __init__(self, response, reason_message=None): 30 """ 31 `response`: the response object 32 33 `reason_message`: if provided, will use this message as the cause 34 of failure instead of assuming it was a misuse of the API. 35 """ 36 self.response = response 37 self.url = response.url 38 self.body = response.request.body 39 self.json = None 40 self.message = None 41 code = response.status_code 42 43 try: 44 self.json = response.json() 45 except JSONDecodeError: 46 pass 47 48 # Did we get a 200 response but (manually) raised anyway? The consumer 49 # method considered this an error. If it did, it MUST tell us why in 50 # the message parameter. We pass this message on to the user. 51 if code != 207: 52 try: 53 response.raise_for_status() 54 if reason_message: 55 self.message = reason_message 56 else: 57 self.message = 'Unexpected response (API client error)' 58 except HTTPError: 59 pass 60 61 if code == 400 and not self.json: 62 self.message = 'Client request error' 63 if code == 500: 64 self.message = 'Internal server error' 65 if self.json and (code == 400 or code == 422 or code == 207): 66 if self.json.get('feedbackList', False): 67 self.feedback = [f for f in self.json.get('feedbackList', [])] or None 68 clue = [f['clue'] for f in self.json['feedbackList'] if f['clue'] not in ['OK', 'Created']] 69 hint = [f['hint'].replace('\'', '\"') for f in self.json['feedbackList'] if f['clue'] not in ['OK', 'Created']] 70 if len(clue) == 1: 71 clue_part = " - Clue: {} ({})".format(clue[0], hint[0]) 72 else: 73 clue_part = " - Clue 1 of {}: {} ({})".format(len(clue), clue[0], hint[0]) 74 else: 75 # No feedback list, but clue in top-leel of dict 76 clue = self.json['jobClue']['clue'] 77 hint = self.json['jobClue']['hint'].replace('\'', '\"') 78 clue_part = ' - Clue: {} ({})'.format(clue, hint) 79 self.message = self.json['status'] + clue_part 80 81 if not self.message: 82 self.message = "Request error: {}".format(code) 83 super().__init__(self.message)
The API request failed. This exception will extract the specific error from the Projectal response if it can find one. To assist in debugging, the response object is attached to the exception which you may inspect for more precise details.
In case of failure of a bulk operation, only the error clue for the first failure is shown. A counter is included to show how many failed (i.e.: 1 of 25).
29 def __init__(self, response, reason_message=None): 30 """ 31 `response`: the response object 32 33 `reason_message`: if provided, will use this message as the cause 34 of failure instead of assuming it was a misuse of the API. 35 """ 36 self.response = response 37 self.url = response.url 38 self.body = response.request.body 39 self.json = None 40 self.message = None 41 code = response.status_code 42 43 try: 44 self.json = response.json() 45 except JSONDecodeError: 46 pass 47 48 # Did we get a 200 response but (manually) raised anyway? The consumer 49 # method considered this an error. If it did, it MUST tell us why in 50 # the message parameter. We pass this message on to the user. 51 if code != 207: 52 try: 53 response.raise_for_status() 54 if reason_message: 55 self.message = reason_message 56 else: 57 self.message = 'Unexpected response (API client error)' 58 except HTTPError: 59 pass 60 61 if code == 400 and not self.json: 62 self.message = 'Client request error' 63 if code == 500: 64 self.message = 'Internal server error' 65 if self.json and (code == 400 or code == 422 or code == 207): 66 if self.json.get('feedbackList', False): 67 self.feedback = [f for f in self.json.get('feedbackList', [])] or None 68 clue = [f['clue'] for f in self.json['feedbackList'] if f['clue'] not in ['OK', 'Created']] 69 hint = [f['hint'].replace('\'', '\"') for f in self.json['feedbackList'] if f['clue'] not in ['OK', 'Created']] 70 if len(clue) == 1: 71 clue_part = " - Clue: {} ({})".format(clue[0], hint[0]) 72 else: 73 clue_part = " - Clue 1 of {}: {} ({})".format(len(clue), clue[0], hint[0]) 74 else: 75 # No feedback list, but clue in top-leel of dict 76 clue = self.json['jobClue']['clue'] 77 hint = self.json['jobClue']['hint'].replace('\'', '\"') 78 clue_part = ' - Clue: {} ({})'.format(clue, hint) 79 self.message = self.json['status'] + clue_part 80 81 if not self.message: 82 self.message = "Request error: {}".format(code) 83 super().__init__(self.message)
response
: the response object
reason_message
: if provided, will use this message as the cause
of failure instead of assuming it was a misuse of the API.
Inherited Members
- builtins.BaseException
- with_traceback
86class ProjectalVersionException(Exception): 87 """ 88 The Projectal server version is incompatible with the version 89 of this library. 90 """ 91 pass
The Projectal server version is incompatible with the version of this library.
Inherited Members
- builtins.Exception
- Exception
- builtins.BaseException
- with_traceback
94class UsageException(Exception): 95 """ 96 The library was used incorrectly and we were able to detect it 97 before making a request. 98 """ 99 pass
The library was used incorrectly and we were able to detect it before making a request.
Inherited Members
- builtins.Exception
- Exception
- builtins.BaseException
- with_traceback