Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 23f8242

Browse files
Chain failure causes on routing table fetching failure (#1219)
When a routing driver (`neo4j[+s[sc]]` URL scheme), fails to fetch a routing table, is swallows all errors from the connection and RT fetching attempts that lead up to the failure and just reports ``` neo4j.exceptions.ServiceUnavailable: Unable to retrieve routing information ``` This hides the relevant information to the user: why did this fail? SSL problems, connectivity issues, unsupported server version, ...? This PR chains all errors (and their causes) as `__cause__` of the top-level `ServiceUnavailable`. When available an `ExceptionGroup` is used (running on Python 3.11+), else all errors are flattened into a single cause chain. ``` | ExceptionGroup: All routing table requests failed (4 sub-exceptions) +-+---------------- 1 ---------------- | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 439, in _connect_secure | s = ssl_context.wrap_socket(s, server_hostname=sni_host) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/lib/python3.11/ssl.py", line 517, in wrap_socket | return self.sslsocket_class._create( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/lib/python3.11/ssl.py", line 1108, in _create | self.do_handshake() | File "/usr/lib/python3.11/ssl.py", line 1379, in do_handshake | self._sslobj.do_handshake() | ssl.SSLEOFError: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1006) | | The above exception was the direct cause of the following exception: | | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 324, in connect | s = cls._connect_secure( | ^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 441, in _connect_secure | raise BoltSecurityError( | neo4j._exceptions.BoltSecurityError: [SSLEOFError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 8: Exec format error) | | The above exception was the direct cause of the following exception: | | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 832, in fetch_routing_table | new_routing_info = self.fetch_routing_info( | ^^^^^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 791, in fetch_routing_info | cx = self._acquire(address, auth, deadline, None) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 416, in _acquire | return connection_creator() | ^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 231, in connection_creator | connection = self.opener( | ^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 710, in opener | return Bolt.open( | ^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt.py", line 364, in open | s, protocol_version = BoltSocket.connect( | ^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 371, in connect | raise ServiceUnavailable( | neo4j.exceptions.ServiceUnavailable: Couldn't connect to [::1]:7687 (resolved to ('[::1]:7687',)): [SSLEOFError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 8: Exec format error) +---------------- 2 ---------------- | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 439, in _connect_secure | s = ssl_context.wrap_socket(s, server_hostname=sni_host) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/lib/python3.11/ssl.py", line 517, in wrap_socket | return self.sslsocket_class._create( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/lib/python3.11/ssl.py", line 1108, in _create | self.do_handshake() | File "/usr/lib/python3.11/ssl.py", line 1379, in do_handshake | self._sslobj.do_handshake() | ssl.SSLEOFError: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1006) | | The above exception was the direct cause of the following exception: | | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 324, in connect | s = cls._connect_secure( | ^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 441, in _connect_secure | raise BoltSecurityError( | neo4j._exceptions.BoltSecurityError: [SSLEOFError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 8: Exec format error) | | The above exception was the direct cause of the following exception: | | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 832, in fetch_routing_table | new_routing_info = self.fetch_routing_info( | ^^^^^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 791, in fetch_routing_info | cx = self._acquire(address, auth, deadline, None) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 416, in _acquire | return connection_creator() | ^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 231, in connection_creator | connection = self.opener( | ^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 710, in opener | return Bolt.open( | ^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt.py", line 364, in open | s, protocol_version = BoltSocket.connect( | ^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 371, in connect | raise ServiceUnavailable( | neo4j.exceptions.ServiceUnavailable: Couldn't connect to 127.0.0.1:7687 (resolved to ('127.0.0.1:7687',)): [SSLEOFError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 8: Exec format error) +---------------- 3 ---------------- | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 324, in connect | s = cls._connect_secure( | ^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 415, in _connect_secure | raise ServiceUnavailable( | neo4j.exceptions.ServiceUnavailable: Timed out trying to establish connection to ResolvedIPv4Address(('172.0.0.1', 7687)) | | The above exception was the direct cause of the following exception: | | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 832, in fetch_routing_table | new_routing_info = self.fetch_routing_info( | ^^^^^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 791, in fetch_routing_info | cx = self._acquire(address, auth, deadline, None) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 416, in _acquire | return connection_creator() | ^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 231, in connection_creator | connection = self.opener( | ^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 710, in opener | return Bolt.open( | ^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt.py", line 364, in open | s, protocol_version = BoltSocket.connect( | ^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 371, in connect | raise ServiceUnavailable( | neo4j.exceptions.ServiceUnavailable: Couldn't connect to 172.0.0.1:7687 (resolved to ('172.0.0.1:7687',)): Timed out trying to establish connection to ResolvedIPv4Address(('172.0.0.1', 7687)) +---------------- 4 ---------------- | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 439, in _connect_secure | s = ssl_context.wrap_socket(s, server_hostname=sni_host) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/lib/python3.11/ssl.py", line 517, in wrap_socket | return self.sslsocket_class._create( | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/usr/lib/python3.11/ssl.py", line 1108, in _create | self.do_handshake() | File "/usr/lib/python3.11/ssl.py", line 1379, in do_handshake | self._sslobj.do_handshake() | ConnectionResetError: [Errno 104] Connection reset by peer | | The above exception was the direct cause of the following exception: | | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 324, in connect | s = cls._connect_secure( | ^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 441, in _connect_secure | raise BoltSecurityError( | neo4j._exceptions.BoltSecurityError: [ConnectionResetError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 104: Connection reset by peer) | | The above exception was the direct cause of the following exception: | | Traceback (most recent call last): | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 832, in fetch_routing_table | new_routing_info = self.fetch_routing_info( | ^^^^^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 791, in fetch_routing_info | cx = self._acquire(address, auth, deadline, None) | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 416, in _acquire | return connection_creator() | ^^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 231, in connection_creator | connection = self.opener( | ^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 710, in opener | return Bolt.open( | ^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt.py", line 364, in open | s, protocol_version = BoltSocket.connect( | ^^^^^^^^^^^^^^^^^^^ | File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 371, in connect | raise ServiceUnavailable( | neo4j.exceptions.ServiceUnavailable: Couldn't connect to 34.78.76.49:7687 (resolved to ('34.78.76.49:7687',)): [ConnectionResetError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 104: Connection reset by peer) +------------------------------------ The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/home/alice/main.py", line 180, in <module> main() File "/home/alice/main.py", line 50, in main driver.verify_connectivity() File "/<neo4j-install-path>/neo4j/_sync/driver.py", line 1054, in verify_connectivity self._get_server_info(session_config) File "/<neo4j-install-path>/neo4j/_sync/driver.py", line 1283, in _get_server_info return session._get_server_info() ^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/<neo4j-install-path>/neo4j/_sync/work/session.py", line 173, in _get_server_info self._connect( File "/<neo4j-install-path>/neo4j/_sync/work/session.py", line 126, in _connect super()._connect( File "/<neo4j-install-path>/neo4j/_sync/work/workspace.py", line 160, in _connect target_db = self._get_routing_target_database( ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ File "/<neo4j-install-path>/neo4j/_sync/work/workspace.py", line 234, in _get_routing_target_database self._pool.update_routing_table( File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 1075, in update_routing_table raise ServiceUnavailable( neo4j.exceptions.ServiceUnavailable: Unable to retrieve routing information ``` ``` Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 439, in _connect_secure s = ssl_context.wrap_socket(s, server_hostname=sni_host) File "/usr/lib/python3.10/ssl.py", line 513, in wrap_socket return self.sslsocket_class._create( File "/usr/lib/python3.10/ssl.py", line 1100, in _create self.do_handshake() File "/usr/lib/python3.10/ssl.py", line 1371, in do_handshake self._sslobj.do_handshake() ssl.SSLEOFError: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1007) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 324, in connect s = cls._connect_secure( File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 441, in _connect_secure raise BoltSecurityError( neo4j._exceptions.BoltSecurityError: [SSLEOFError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 8: Exec format error) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 832, in fetch_routing_table new_routing_info = self.fetch_routing_info( File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 791, in fetch_routing_info cx = self._acquire(address, auth, deadline, None) File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 416, in _acquire return connection_creator() File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 231, in connection_creator connection = self.opener( File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 710, in opener return Bolt.open( File "/<neo4j-install-path>/neo4j/_sync/io/_bolt.py", line 364, in open s, protocol_version = BoltSocket.connect( File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 371, in connect raise ServiceUnavailable( neo4j.exceptions.ServiceUnavailable: Couldn't connect to [::1]:7687 (resolved to ('[::1]:7687',)): [SSLEOFError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 8: Exec format error) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 439, in _connect_secure s = ssl_context.wrap_socket(s, server_hostname=sni_host) File "/usr/lib/python3.10/ssl.py", line 513, in wrap_socket return self.sslsocket_class._create( File "/usr/lib/python3.10/ssl.py", line 1100, in _create self.do_handshake() File "/usr/lib/python3.10/ssl.py", line 1371, in do_handshake self._sslobj.do_handshake() ssl.SSLEOFError: [SSL: UNEXPECTED_EOF_WHILE_READING] EOF occurred in violation of protocol (_ssl.c:1007) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 324, in connect s = cls._connect_secure( File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 441, in _connect_secure raise BoltSecurityError( neo4j._exceptions.BoltSecurityError: [SSLEOFError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 8: Exec format error) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 832, in fetch_routing_table new_routing_info = self.fetch_routing_info( File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 791, in fetch_routing_info cx = self._acquire(address, auth, deadline, None) File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 416, in _acquire return connection_creator() File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 231, in connection_creator connection = self.opener( File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 710, in opener return Bolt.open( File "/<neo4j-install-path>/neo4j/_sync/io/_bolt.py", line 364, in open s, protocol_version = BoltSocket.connect( File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 371, in connect raise ServiceUnavailable( neo4j.exceptions.ServiceUnavailable: Couldn't connect to 127.0.0.1:7687 (resolved to ('127.0.0.1:7687',)): [SSLEOFError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 8: Exec format error) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 324, in connect s = cls._connect_secure( File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 415, in _connect_secure raise ServiceUnavailable( neo4j.exceptions.ServiceUnavailable: Timed out trying to establish connection to ResolvedIPv4Address(('172.0.0.1', 7687)) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 832, in fetch_routing_table new_routing_info = self.fetch_routing_info( File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 791, in fetch_routing_info cx = self._acquire(address, auth, deadline, None) File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 416, in _acquire return connection_creator() File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 231, in connection_creator connection = self.opener( File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 710, in opener return Bolt.open( File "/<neo4j-install-path>/neo4j/_sync/io/_bolt.py", line 364, in open s, protocol_version = BoltSocket.connect( File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 371, in connect raise ServiceUnavailable( neo4j.exceptions.ServiceUnavailable: Couldn't connect to 172.0.0.1:7687 (resolved to ('172.0.0.1:7687',)): Timed out trying to establish connection to ResolvedIPv4Address(('172.0.0.1', 7687)) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 439, in _connect_secure s = ssl_context.wrap_socket(s, server_hostname=sni_host) File "/usr/lib/python3.10/ssl.py", line 513, in wrap_socket return self.sslsocket_class._create( File "/usr/lib/python3.10/ssl.py", line 1100, in _create self.do_handshake() File "/usr/lib/python3.10/ssl.py", line 1371, in do_handshake self._sslobj.do_handshake() ConnectionResetError: [Errno 104] Connection reset by peer The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 324, in connect s = cls._connect_secure( File "/<neo4j-install-path>/neo4j/_async_compat/network/_bolt_socket.py", line 441, in _connect_secure raise BoltSecurityError( neo4j._exceptions.BoltSecurityError: [ConnectionResetError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 104: Connection reset by peer) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 832, in fetch_routing_table new_routing_info = self.fetch_routing_info( File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 791, in fetch_routing_info cx = self._acquire(address, auth, deadline, None) File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 416, in _acquire return connection_creator() File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 231, in connection_creator connection = self.opener( File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 710, in opener return Bolt.open( File "/<neo4j-install-path>/neo4j/_sync/io/_bolt.py", line 364, in open s, protocol_version = BoltSocket.connect( File "/<neo4j-install-path>/neo4j/_sync/io/_bolt_socket.py", line 371, in connect raise ServiceUnavailable( neo4j.exceptions.ServiceUnavailable: Couldn't connect to 34.78.76.49:7687 (resolved to ('34.78.76.49:7687',)): [ConnectionResetError] Connection Failed. Please ensure that your database is listening on the correct host and port and that you have enabled encryption if required. Note that the default encryption setting has changed in Neo4j 4.0. See the docs for more information. Failed to establish encrypted connection. (code 104: Connection reset by peer) The above exception was the direct cause of the following exception: Traceback (most recent call last): File "//home/alice/main.py", line 180, in <module> main() File "//home/alice/main.py", line 50, in main driver.verify_connectivity() File "/<neo4j-install-path>/neo4j/_sync/driver.py", line 1054, in verify_connectivity self._get_server_info(session_config) File "/<neo4j-install-path>/neo4j/_sync/driver.py", line 1283, in _get_server_info return session._get_server_info() File "/<neo4j-install-path>/neo4j/_sync/work/session.py", line 173, in _get_server_info self._connect( File "/<neo4j-install-path>/neo4j/_sync/work/session.py", line 126, in _connect super()._connect( File "/<neo4j-install-path>/neo4j/_sync/work/workspace.py", line 160, in _connect target_db = self._get_routing_target_database( File "/<neo4j-install-path>/neo4j/_sync/work/workspace.py", line 234, in _get_routing_target_database self._pool.update_routing_table( File "/<neo4j-install-path>/neo4j/_sync/io/_pool.py", line 1075, in update_routing_table raise ServiceUnavailable( neo4j.exceptions.ServiceUnavailable: Unable to retrieve routing information ```
1 parent 258a319 commit 23f8242

File tree

4 files changed

+234
-10
lines changed

4 files changed

+234
-10
lines changed

‎src/neo4j/_async/io/_pool.py

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import asyncio
2121
import logging
2222
import math
23+
import sys
2324
from collections import (
2425
defaultdict,
2526
deque,
@@ -53,6 +54,7 @@
5354
DriverError,
5455
Neo4jError,
5556
ReadServiceUnavailable,
57+
RoutingServiceUnavailable,
5658
ServiceUnavailable,
5759
SessionExpired,
5860
WriteServiceUnavailable,
@@ -810,6 +812,7 @@ async def fetch_routing_table(
810812
imp_user,
811813
bookmarks,
812814
auth,
815+
ignored_errors=None,
813816
):
814817
"""
815818
Fetch a routing table from a given router address.
@@ -823,6 +826,7 @@ async def fetch_routing_table(
823826
:type imp_user: str or None
824827
:param bookmarks: bookmarks used when fetching routing table
825828
:param auth: auth
829+
:param ignored_errors: optional list to accumulate ignored errors in
826830
827831
:returns: a new RoutingTable instance or None if the given router is
828832
currently unable to provide routing information
@@ -843,15 +847,16 @@ async def fetch_routing_table(
843847
# router. Hence, the driver should fail fast during discovery.
844848
if e._is_fatal_during_discovery():
845849
raise
846-
except (ServiceUnavailable, SessionExpired):
847-
pass
850+
if ignored_errors is not None:
851+
ignored_errors.append(e)
852+
except (ServiceUnavailable, SessionExpired) as e:
853+
if ignored_errors is not None:
854+
ignored_errors.append(e)
848855
if not new_routing_info:
849856
log.debug(
850857
"[#0000] _: <POOL> failed to fetch routing info from %r",
851858
address,
852859
)
853-
# TODO: 7.0 - when Python 3.11+ is the minimum,
854-
# use exception groups instead of swallowing discovery errors
855860
return None
856861
else:
857862
servers = new_routing_info[0]["servers"]
@@ -876,6 +881,12 @@ async def fetch_routing_table(
876881
"server %s",
877882
address,
878883
)
884+
if ignored_errors is not None:
885+
ignored_errors.append(
886+
RoutingServiceUnavailable(
887+
"Rejected routing table: no routers"
888+
)
889+
)
879890
return None
880891

881892
# No readers
@@ -884,6 +895,12 @@ async def fetch_routing_table(
884895
"[#0000] _: <POOL> no read servers returned from server %s",
885896
address,
886897
)
898+
if ignored_errors is not None:
899+
ignored_errors.append(
900+
ReadServiceUnavailable(
901+
"Rejected routing table: no readers"
902+
)
903+
)
887904
return None
888905

889906
# At least one of each is fine, so return this table
@@ -898,6 +915,7 @@ async def _update_routing_table_from(
898915
auth,
899916
acquisition_timeout,
900917
database_callback,
918+
ignored_errors=None,
901919
):
902920
"""
903921
Try to update routing tables with the given routers.
@@ -924,6 +942,7 @@ async def _update_routing_table_from(
924942
imp_user=imp_user,
925943
bookmarks=bookmarks,
926944
auth=auth,
945+
ignored_errors=ignored_errors,
927946
)
928947
if new_routing_table is not None:
929948
new_database = new_routing_table.database
@@ -973,6 +992,7 @@ async def update_routing_table(
973992
acquisition_timeout = acquisition_timeout_to_deadline(
974993
acquisition_timeout
975994
)
995+
errors = []
976996
async with self.refresh_lock:
977997
routing_table = await self.get_routing_table(database)
978998
if routing_table is not None:
@@ -997,6 +1017,7 @@ async def update_routing_table(
9971017
auth=auth,
9981018
acquisition_timeout=acquisition_timeout,
9991019
database_callback=database_callback,
1020+
ignored_errors=errors,
10001021
)
10011022
):
10021023
# Why is only the first initial routing address used?
@@ -1009,6 +1030,7 @@ async def update_routing_table(
10091030
auth=auth,
10101031
acquisition_timeout=acquisition_timeout,
10111032
database_callback=database_callback,
1033+
ignored_errors=errors,
10121034
):
10131035
return
10141036

@@ -1022,14 +1044,41 @@ async def update_routing_table(
10221044
auth=auth,
10231045
acquisition_timeout=acquisition_timeout,
10241046
database_callback=database_callback,
1047+
ignored_errors=errors,
10251048
)
10261049
):
10271050
# Why is only the first initial routing address used?
10281051
return
10291052

10301053
# None of the routers have been successful, so just fail
10311054
log.error("Unable to retrieve routing information")
1032-
raise ServiceUnavailable("Unable to retrieve routing information")
1055+
if sys.version_info >= (3, 11):
1056+
e = ExceptionGroup( # noqa: F821 # version guard in place
1057+
"All routing table requests failed", errors
1058+
)
1059+
else:
1060+
e = None
1061+
for error in errors:
1062+
if e is None:
1063+
e = error
1064+
continue
1065+
cause = error
1066+
seen_causes = {id(cause)}
1067+
while True:
1068+
next_cause = getattr(cause, "__cause__", None)
1069+
if next_cause is None:
1070+
break
1071+
if id(next_cause) in seen_causes:
1072+
# Avoid infinite recursion in case of circular
1073+
# references.
1074+
break
1075+
cause = next_cause
1076+
seen_causes.add(id(cause))
1077+
cause.__cause__ = e
1078+
e = error
1079+
raise ServiceUnavailable(
1080+
"Unable to retrieve routing information"
1081+
) from e
10331082

10341083
async def update_connection_pool(self):
10351084
async with self.refresh_lock:

‎src/neo4j/_sync/io/_pool.py

Lines changed: 54 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /