X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/48580ba7a6608c89e91afad4b73f2861aafbd7b2..ba34a22d9918ae97306472c04701e69090821c82:/sdk/python/arvados/errors.py diff --git a/sdk/python/arvados/errors.py b/sdk/python/arvados/errors.py index 16f4096572..15b1f6d4b9 100644 --- a/sdk/python/arvados/errors.py +++ b/sdk/python/arvados/errors.py @@ -1,7 +1,10 @@ +# Copyright (C) The Arvados Authors. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 + # errors.py - Arvados-specific exceptions. import json -import requests from apiclient import errors as apiclient_errors from collections import OrderedDict @@ -9,49 +12,62 @@ from collections import OrderedDict class ApiError(apiclient_errors.HttpError): def _get_reason(self): try: - return '; '.join(json.loads(self.content)['errors']) + return '; '.join(json.loads(self.content.decode('utf-8'))['errors']) except (KeyError, TypeError, ValueError): 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=()) + def __init__(self, message='', request_errors=(), label=""): + """KeepRequestError(message='', request_errors=(), label="") - Arguments: - * message: A human-readable message describing what Keep operation + :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. + + :request_errors: + An iterable that yields 2-tuples of keys (where the key refers to + some operation that was attempted) 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 + request_errors() method. + + :label: + A label indicating the type of value in the 'key' position of request_errors. + """ - self._service_errors = OrderedDict(service_errors) - if self._service_errors: + self.label = label + self._request_errors = OrderedDict(request_errors) + if self._request_errors: exc_reports = [self._format_error(*err_pair) - for err_pair in self._service_errors.iteritems()] + for err_pair in self._request_errors.items()] 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}" + def _format_error(self, key, error): + if isinstance(error, HttpError): + 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) + err_fmt = "{} {} raised {e.__class__.__name__} ({e})" + return err_fmt.format(self.label, key, e=error) - def service_errors(self): - """service_errors() -> OrderedDict + def request_errors(self): + """request_errors() -> OrderedDict - The keys of the dictionary are Keep service URLs. + The keys of the dictionary are described by `self.label` The corresponding value is the exception raised when sending the request to it.""" - return self._service_errors + return self._request_errors + + +class HttpError(Exception): + def __init__(self, status_code, reason): + self.status_code = status_code + self.reason = reason class ArgumentError(Exception): @@ -66,6 +82,8 @@ class KeepReadError(KeepRequestError): pass class KeepWriteError(KeepRequestError): pass +class KeepCacheError(KeepRequestError): + pass class NotFoundError(KeepReadError): pass class NotImplementedError(Exception):