File: exceptions.rst

package info (click to toggle)
python-globus-sdk 3.54.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,032 kB
  • sloc: python: 34,226; sh: 44; makefile: 31
file content (164 lines) | stat: -rw-r--r-- 4,472 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
Exceptions
==========

All Globus SDK errors inherit from ``GlobusError``, and all SDK error classes
are importable from ``globus_sdk``.

You can therefore capture *all* errors thrown by the SDK by looking for
``GlobusError``, as in

.. code-block:: python

    import logging
    from globus_sdk import TransferClient, GlobusError

    try:
        tc = TransferClient(...)
        # search with no parameters will throw an exception
        eps = tc.endpoint_search()
    except GlobusError:
        logging.exception("Globus Error!")
        raise

In most cases, it's best to look for specific subclasses of ``GlobusError``.
For example, to write code which is distinguishes between network failures and
unexpected API conditions, you'll want to look for ``NetworkError`` and
``GlobusAPIError``

.. code-block:: python

    import logging
    from globus_sdk import TransferClient, GlobusError, GlobusAPIError, NetworkError

    try:
        tc = TransferClient(...)

        eps = tc.endpoint_search(filter_fulltext="myendpointsearch")

        for ep in eps:
            print(ep["display_name"])

        ...
    except GlobusAPIError as e:
        # Error response from the REST service, check the code and message for
        # details.
        logging.error(
            "Got a Globus API Error\n"
            f"Error Code: {e.code}\n"
            f"Error Message: {e.message}"
        )
        raise e
    except NetworkError:
        logging.error("Network Failure. Possibly a firewall or connectivity issue")
        raise
    except GlobusError:
        logging.exception("Totally unexpected GlobusError!")
        raise
    else:
        ...

Of course, if you want to learn more information about the response, you should
inspect it more than this.

All errors raised by the SDK should be instances of ``GlobusError``.
Malformed calls to Globus SDK methods typically raise ``GlobusSDKUsageError``,
but, in rare cases, may raise standard python exceptions (``ValueError``,
``OSError``, etc.)

Error Classes
-------------

.. autoclass:: globus_sdk.GlobusError
   :members:
   :show-inheritance:

.. autoclass:: globus_sdk.GlobusSDKUsageError
   :members:
   :show-inheritance:

.. autoclass:: globus_sdk.ValidationError
   :members:
   :show-inheritance:

.. autoclass:: globus_sdk.GlobusAPIError
   :members:
   :show-inheritance:

.. autoclass:: globus_sdk.NetworkError
   :members:
   :show-inheritance:

.. autoclass:: globus_sdk.GlobusConnectionError
   :members:
   :show-inheritance:

.. autoclass:: globus_sdk.GlobusTimeoutError
   :members:
   :show-inheritance:

.. autoclass:: globus_sdk.GlobusConnectionTimeoutError
   :members:
   :show-inheritance:

.. _error_subdocuments:

ErrorSubdocuments
-----------------

Errors returned from APIs may define a series of subdocuments, each containing
an error object. This is used if there were multiple errors encountered and the
API wants to send them back all at once.

All instances of ``GlobusAPIError`` define an attribute, ``errors``, which is
an array of ``ErrorSubdocument``\s.

Error handling code can inspect these sub-errors like so:

.. code-block:: python

    try:
        some_complex_globus_operation()
    except GlobusAPIError as e:
        if e.errors:
            print("sub-errors encountered")
            print("(code, message)")
            for suberror in e.errors:
                print(f"({suberror.code}, {suberror.message}")

.. autoclass:: globus_sdk.exc.ErrorSubdocument
    :members:

.. _error_info:

ErrorInfo
---------

``GlobusAPIError`` and its subclasses all support an ``info`` property which
may contain parsed error data. The ``info`` is guaranteed to be there, but its
attributes should be tested before use, as in

.. code-block:: python

    # if 'err' is an API error, then 'err.info' is an 'ErrorInfoContainer',
    # a wrapper which holds ErrorInfo objects
    # 'err.info.consent_required' is a 'ConsentRequiredInfo', which should be
    # tested for truthy/falsey-ness before use
    if err.info.consent_required:
        print(
            "Got a ConsentRequired error with scopes:",
            err.info.consent_required.required_scopes,
        )

.. autoclass:: globus_sdk.exc.ErrorInfoContainer
    :members:

.. autoclass:: globus_sdk.exc.ErrorInfo
    :members:

.. autoclass:: globus_sdk.exc.AuthorizationParameterInfo
    :members:
    :show-inheritance:

.. autoclass:: globus_sdk.exc.ConsentRequiredInfo
    :members:
    :show-inheritance: