diff --git a/CHANGES.rst b/CHANGES.rst index db094c5e..398c67b0 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -6,6 +6,7 @@ Unreleased ========== - Modernize project definition to latest Python best practices. Thanks, @surister. - Exceptions: Exceptions from the BLOB API now include their full names. +- Changed connection behaviour to fail early if the database cluster does not respond 2025/01/30 2.0.0 ================ diff --git a/docs/by-example/client.rst b/docs/by-example/client.rst index a06e1036..a693374d 100644 --- a/docs/by-example/client.rst +++ b/docs/by-example/client.rst @@ -29,12 +29,8 @@ respond, the request is automatically routed to the next server: >>> connection = client.connect([invalid_host, crate_host]) >>> connection.close() -If no ``servers`` are given, the default one ``http://127.0.0.1:4200`` is used: - - >>> connection = client.connect() - >>> connection.client._active_servers - ['http://127.0.0.1:4200'] - >>> connection.close() +If no ``servers`` are supplied to the ``connect`` method, the default address +``http://127.0.0.1:4200`` is used. If the option ``error_trace`` is set to ``True``, the client will print a whole traceback if a server error occurs: diff --git a/src/crate/client/connection.py b/src/crate/client/connection.py index 0638a018..d05f2649 100644 --- a/src/crate/client/connection.py +++ b/src/crate/client/connection.py @@ -18,8 +18,10 @@ # However, if you have executed another commercial license agreement # with Crate these terms will supersede the license and you may use the # software solely pursuant to the terms of the relevant commercial agreement. +import json from verlib2 import Version +from verlib2.packaging.version import InvalidVersion from .blob import BlobContainer from .cursor import Cursor @@ -197,14 +199,21 @@ def get_blob_container(self, container_name): def _lowest_server_version(self): lowest = None + server_count = len(self.client.active_servers) + connection_errors = [] for server in self.client.active_servers: try: _, _, version = self.client.server_infos(server) version = Version(version) - except (ValueError, ConnectionError): + except ConnectionError as ex: + connection_errors.append(ex) + continue + except (ValueError, InvalidVersion): continue if not lowest or version < lowest: lowest = version + if connection_errors and len(connection_errors) == server_count: + raise ConnectionError(json.dumps(list(map(str, connection_errors)))) return lowest or Version("0.0.0") def __repr__(self): diff --git a/tests/client/test_connection.py b/tests/client/test_connection.py index 90b121f2..1eb496c0 100644 --- a/tests/client/test_connection.py +++ b/tests/client/test_connection.py @@ -4,6 +4,7 @@ import pytest from urllib3 import Timeout +import crate.client.exceptions from crate.client import connect from crate.client.connection import Connection from crate.client.exceptions import ProgrammingError @@ -12,6 +13,13 @@ from .settings import crate_host +def test_invalid_server_address(): + client = Client(servers="localhost:4202") + with pytest.raises(crate.client.exceptions.ConnectionError) as excinfo: + connect(client=client) + assert excinfo.match("Server not available") + + def test_lowest_server_version(): """ Verify the lowest server version is correctly set.