Source code for py2neo.errors

#!/usr/bin/env python
# -*- encoding: utf-8 -*-

# Copyright 2011-2021, Nigel Small
#
# 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.


__all__ = [
    "Neo4jError",
    "ClientError",
    "DatabaseError",
    "TransientError",
    "ConnectionUnavailable",
    "ConnectionBroken",
    "ConnectionLimit",
    "ServiceUnavailable",
    "WriteServiceUnavailable",
    "ProtocolError",
]


[docs] class Neo4jError(Exception): """ Base exception class for modelling error status codes returned by Neo4j. For details of the status codes available, visit: https://neo4j.com/docs/status-codes/current/ """ @classmethod def hydrate(cls, data): code = data.get("code") message = data.get("message") return cls(message, code)
[docs] @classmethod def split_code(cls, code): """ Splits a status code, returning a 3-tuple of classification, category and title. """ try: parts = code.split(".") except AttributeError: raise ValueError(code) else: if len(parts) == 4 and parts[0] == "Neo": return parts[1], parts[2], parts[3] else: raise ValueError(code)
def __new__(cls, message, code): classification, _, _ = cls.split_code(code) if classification == "ClientError": return Exception.__new__(ClientError) elif classification == "DatabaseError": return Exception.__new__(DatabaseError) elif classification == "TransientError": return Exception.__new__(TransientError) else: return Exception.__new__(cls) def __init__(self, message, code): super(Neo4jError, self).__init__(message) self.__code = code self.__classification, self.__category, self.__title = self.split_code(self.__code) def __str__(self): return "[%s.%s] %s" % (self.category, self.title, super(Neo4jError, self).__str__()) @property def code(self): return self.__code @property def classification(self): return self.__classification @property def category(self): return self.__category @property def title(self): return self.__title @property def message(self): return self.args[0] def should_retry(self): return False def should_invalidate_routing_table(self): return False
[docs] class ClientError(Neo4jError): def should_invalidate_routing_table(self): return self.category == "Cluster" and self.title == "NotALeader" def should_retry(self): return self.category == "Cluster" and self.title == "NotALeader"
[docs] class DatabaseError(Neo4jError): pass
[docs] class TransientError(Neo4jError): def should_retry(self): return True
[docs] class ConnectionUnavailable(Exception): """ Raised when a connection cannot be acquired. """
[docs] class ConnectionBroken(Exception): """ Raised when a connection breaks during use. """
[docs] class ConnectionLimit(Exception): """ Raised when no further connections are available due to a configured resource limit. """
[docs] class ServiceUnavailable(Exception): """ Raised when no read or write service is available from a Neo4j installation. """ def __init__(self, *args): super(ServiceUnavailable, self).__init__(*args)
[docs] class WriteServiceUnavailable(ServiceUnavailable): """ Raised when no write service is available from a Neo4j installation, but a read service may still be available. """ def __init__(self, *args): super(WriteServiceUnavailable, self).__init__(*args)
[docs] class ProtocolError(Exception): """ Raised when a protocol violation or other unrecoverable protocol error occurs. These errors cannot be remedied automatically, and may result from a bug in the driver or server software. """
# TODO: add hints for users when they see this error