projectal.errors API documentation

# projectal.errors

View Source

      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

class LoginException(builtins.Exception): View Source

    10class LoginException(Exception):
    11    """Failed to log in with the credentials provided."""
    12
    13    pass

Failed to log in with the credentials provided.

class UnsupportedException(builtins.Exception): View Source

    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.

class ProjectalException(builtins.Exception): View Source

    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).

ProjectalException(response, reason_message=None) View Source

    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.

response
url
body
json
message
class ProjectalVersionException(builtins.Exception): View Source

    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.

class UsageException(builtins.Exception): View Source

    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.