Source code for pynessie.error

# -*- coding: utf-8 -*-
#
# Copyright (C) 2020 Dremio
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
"""Nessie Exceptions."""
from typing import Optional

import simplejson as json


[docs]class NessieException(Exception): """Base Nessie exception.""" def __init__( self, parsed_response: dict, status: int, url: str, reason: str, msg: str = None, ) -> None: """Construct base Nessie Exception.""" if "message" in parsed_response: exception_msg = reason + ": " + parsed_response["message"] elif msg: exception_msg = reason + ": " + msg else: # If we did not get a JSON response for a 500 error, use a generic message. # In this case the HTML response contents are likely not user-friendly anyway. if 500 <= status <= 599: exception_msg = "Internal Server Error" else: exception_msg = "Unknown Error" super().__init__(exception_msg) self.status_code = status self.server_message = parsed_response.get("message", str(parsed_response)) self.server_status = parsed_response.get("status", "UNKNOWN") self.error_code = parsed_response.get("errorCode", "UNKNOWN") self.server_stack_trace = parsed_response.get("serverStackTrace") self.url = url
[docs] def json(self) -> str: """Dump this exception as a json object.""" return json.dumps( dict( server_message=self.server_message, error_code=self.error_code, server_status=self.server_status, server_stack_trace=self.server_stack_trace, status_code=self.status_code, url=self.url, msg=" ".join(self.args), ) )
[docs]class NessieUnauthorizedException(NessieException): """Nessie exception for login error 401.""" pass
[docs]class NessiePermissionException(NessieException): """Nessie exception for permission error 403.""" pass
[docs]class NessieNotFoundException(NessieException): """Generic Nessie exception for not found error 404.""" pass
[docs]class NessieReferenceNotFoundException(NessieNotFoundException): """This exception is thrown when a requested reference is not present in the store.""" pass
[docs]class NessieContentNotFoundException(NessieNotFoundException): """This exception is thrown when the requested content object is not present in the store.""" pass
[docs]class NessiePreconidtionFailedException(NessieException): """Nessie exception for pre-condition failed error 412.""" pass
[docs]class NessieConflictException(NessieException): """Generic Nessie exception for conflict error 409.""" pass
[docs]class NessieReferenceAlreadyExistsException(NessieConflictException): """Reference not found. This exception is thrown when a reference could not be created because another reference with the same name is already present in the store. """ pass
[docs]class NessieReferenceConflictException(NessieConflictException): """Expected hash did not match actual hash on a reference. This exception is thrown when the hash associated with a named reference does not match with the hash provided by the caller. """ pass
[docs]class NessieServerException(NessieException): """Nessie exception for server errors 5xx.""" pass
[docs]class NessieCliError(Exception): """Base Nessie CLI related errors.""" def __init__(self, title: str, msg: str = None) -> None: """Construct base Nessie CLI Error.""" super().__init__() self.title = title self.msg = msg
[docs] def json(self) -> str: """Dump this error as a json object.""" return json.dumps(dict(title=self.title, message=self.msg))
def _create_nessie_exception(error: dict, status: int, reason: str, url: str) -> Optional[Exception]: if "errorCode" not in error: return None error_code = error["errorCode"] if error_code == "REFERENCE_NOT_FOUND": return NessieReferenceNotFoundException(error, status, url, reason) if error_code == "REFERENCE_ALREADY_EXISTS": return NessieReferenceAlreadyExistsException(error, status, url, reason) if error_code == "CONTENT_NOT_FOUND": return NessieContentNotFoundException(error, status, url, reason) if error_code == "REFERENCE_CONFLICT": return NessieReferenceConflictException(error, status, url, reason) return None def _create_exception(error: dict, status: int, reason: str, url: str) -> Exception: if 400 <= status < 500: reason = f"Client Error {reason}" elif 500 <= status < 600: reason = f"Server Error {reason}" ex = _create_nessie_exception(error, status, reason, url) if ex: return ex if status == 412: return NessiePreconidtionFailedException(error, status, url, reason, msg="Unable to complete transaction, please retry.") if status == 401: return NessieUnauthorizedException(error, status, url, reason, msg="Unauthorized to access API endpoint") if status == 403: return NessiePermissionException(error, status, url, reason, msg="Insufficient permissions to access " + url) if status == 404: return NessieNotFoundException(error, status, url, reason, msg="Entity not found at " + url) if status == 409: return NessieConflictException(error, status, url, reason, msg="Unable to complete transaction.") if 500 <= status <= 599: return NessieServerException(error, status, url, reason) return NessieException(error, status, url, reason)