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:
|