Skip to content

Commit

Permalink
Improve error output for master discovery (#2720)
Browse files Browse the repository at this point in the history
Make MasterNotFoundError exception more precise in the case of
ConnectionError and TimeoutError to help the user to identify
configuration errors

Co-authored-by: Marc Schöchlin <marc.schoechlin@flipapp.de>
  • Loading branch information
scoopex and Marc Schöchlin committed Apr 27, 2023
1 parent fddd3d6 commit 8e0b84d
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
* Fix Sentinel.execute_command doesn't execute across the entire sentinel cluster bug (#2458)
* Added a replacement for the default cluster node in the event of failure (#2463)
* Fix for Unhandled exception related to self.host with unix socket (#2496)
* Improve error output for master discovery

* 4.1.3 (Feb 8, 2022)
* Fix flushdb and flushall (#1926)
Expand Down
10 changes: 8 additions & 2 deletions redis/asyncio/sentinel.py
Original file line number Diff line number Diff line change
Expand Up @@ -254,10 +254,12 @@ async def discover_master(self, service_name: str):
Returns a pair (address, port) or raises MasterNotFoundError if no
master is found.
"""
collected_errors = list()
for sentinel_no, sentinel in enumerate(self.sentinels):
try:
masters = await sentinel.sentinel_masters()
except (ConnectionError, TimeoutError):
except (ConnectionError, TimeoutError) as e:
collected_errors.append(f"{sentinel} - {e!r}")
continue
state = masters.get(service_name)
if state and self.check_master_state(state, service_name):
Expand All @@ -267,7 +269,11 @@ async def discover_master(self, service_name: str):
self.sentinels[0],
)
return state["ip"], state["port"]
raise MasterNotFoundError(f"No master found for {service_name!r}")

error_info = ""
if len(collected_errors) > 0:
error_info = f" : {', '.join(collected_errors)}"
raise MasterNotFoundError(f"No master found for {service_name!r}{error_info}")

def filter_slaves(
self, slaves: Iterable[Mapping]
Expand Down
10 changes: 8 additions & 2 deletions redis/sentinel.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,12 @@ def discover_master(self, service_name):
Returns a pair (address, port) or raises MasterNotFoundError if no
master is found.
"""
collected_errors = list()
for sentinel_no, sentinel in enumerate(self.sentinels):
try:
masters = sentinel.sentinel_masters()
except (ConnectionError, TimeoutError):
except (ConnectionError, TimeoutError) as e:
collected_errors.append(f"{sentinel} - {e!r}")
continue
state = masters.get(service_name)
if state and self.check_master_state(state, service_name):
Expand All @@ -243,7 +245,11 @@ def discover_master(self, service_name):
self.sentinels[0],
)
return state["ip"], state["port"]
raise MasterNotFoundError(f"No master found for {service_name!r}")

error_info = ""
if len(collected_errors) > 0:
error_info = f" : {', '.join(collected_errors)}"
raise MasterNotFoundError(f"No master found for {service_name!r}{error_info}")

def filter_slaves(self, slaves):
"Remove slaves that are in an ODOWN or SDOWN state"
Expand Down

0 comments on commit 8e0b84d

Please sign in to comment.