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