X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/4335bce9369b5df234c5d68c4deff820ca2c28d1..ad76f76cdd557d61497aa0ff26e0537788f2d5b6:/sdk/python/arvados/errors.py diff --git a/sdk/python/arvados/errors.py b/sdk/python/arvados/errors.py index 4740a2d919..16f4096572 100644 --- a/sdk/python/arvados/errors.py +++ b/sdk/python/arvados/errors.py @@ -1,7 +1,10 @@ # errors.py - Arvados-specific exceptions. import json +import requests + from apiclient import errors as apiclient_errors +from collections import OrderedDict class ApiError(apiclient_errors.HttpError): def _get_reason(self): @@ -11,6 +14,46 @@ class ApiError(apiclient_errors.HttpError): return super(ApiError, self)._get_reason() +class KeepRequestError(Exception): + """Base class for errors accessing Keep services.""" + def __init__(self, message='', service_errors=()): + """KeepRequestError(message='', service_errors=()) + + Arguments: + * message: A human-readable message describing what Keep operation + failed. + * service_errors: An iterable that yields 2-tuples of Keep + service URLs to the error encountered when talking to + it--either an exception, or an HTTP response object. These + will be packed into an OrderedDict, available through the + service_errors() method. + """ + self._service_errors = OrderedDict(service_errors) + if self._service_errors: + exc_reports = [self._format_error(*err_pair) + for err_pair in self._service_errors.iteritems()] + base_msg = "{}: {}".format(message, "; ".join(exc_reports)) + else: + base_msg = message + super(KeepRequestError, self).__init__(base_msg) + self.message = message + + def _format_error(self, service_root, error): + if isinstance(error, requests.Response): + err_fmt = "{} responded with {e.status_code} {e.reason}" + else: + err_fmt = "{} raised {e.__class__.__name__} ({e})" + return err_fmt.format(service_root, e=error) + + def service_errors(self): + """service_errors() -> OrderedDict + + The keys of the dictionary are Keep service URLs. + The corresponding value is the exception raised when sending the + request to it.""" + return self._service_errors + + class ArgumentError(Exception): pass class SyntaxError(Exception): @@ -19,9 +62,9 @@ class AssertionError(Exception): pass class CommandFailedError(Exception): pass -class KeepReadError(Exception): +class KeepReadError(KeepRequestError): pass -class KeepWriteError(Exception): +class KeepWriteError(KeepRequestError): pass class NotFoundError(KeepReadError): pass @@ -31,3 +74,5 @@ class NoKeepServersError(Exception): pass class StaleWriterStateError(Exception): pass +class FeatureNotEnabledError(Exception): + pass