Skip to content

Commit e7fcd7b

Browse files
committed
Better exception handling
1 parent da5378c commit e7fcd7b

File tree

1 file changed

+26
-14
lines changed

1 file changed

+26
-14
lines changed

redis/asyncio/cluster.py

+26-14
Original file line numberDiff line numberDiff line change
@@ -1515,7 +1515,7 @@ async def _execute(
15151515
allow_redirections: bool = True,
15161516
) -> List[Any]:
15171517
todo = [
1518-
cmd for cmd in stack if not cmd.result or isinstance(cmd.result, Exception)
1518+
cmd for cmd in stack if not cmd.unwrap_result() or cmd.get_all_exceptions()
15191519
]
15201520

15211521
nodes = {}
@@ -1548,18 +1548,22 @@ async def _execute(
15481548
if allow_redirections:
15491549
# send each errored command individually
15501550
for cmd in todo:
1551-
if isinstance(cmd.result, (TryAgainError, MovedError, AskError)):
1552-
try:
1553-
result = await client.execute_command(
1554-
*cmd.args, **cmd.kwargs
1555-
)
1556-
except Exception as e:
1557-
result = e
1551+
for name, exc in cmd.get_all_exceptions():
1552+
if isinstance(exc, (TryAgainError, MovedError, AskError)):
1553+
try:
1554+
result = await client.execute_command(
1555+
*cmd.args, **cmd.kwargs
1556+
)
1557+
except Exception as e:
1558+
result = e
15581559

1559-
if isinstance(result, dict):
1560-
cmd.result = result
1561-
else:
1562-
cmd.set_node_result(cmd.target_nodes[0].name, result)
1560+
if isinstance(result, dict):
1561+
cmd.result = result
1562+
else:
1563+
cmd.set_node_result(name, result)
1564+
1565+
# We have already retried the command on all nodes.
1566+
break
15631567

15641568
if raise_on_error:
15651569
for cmd in todo:
@@ -1583,11 +1587,16 @@ async def _execute(
15831587
# to replace it.
15841588
# Note: when the error is raised we'll reset the default node in the
15851589
# caller function.
1590+
has_exc = False
15861591
for cmd in default_node[1]:
15871592
# Check if it has a command that failed with a relevant
15881593
# exception
1589-
if type(cmd.result) in self.__class__.ERRORS_ALLOW_RETRY:
1590-
client.replace_default_node()
1594+
for name, exc in cmd.get_all_exceptions():
1595+
if type(exc) in self.__class__.ERRORS_ALLOW_RETRY:
1596+
client.replace_default_node()
1597+
has_exc = True
1598+
break
1599+
if has_exc:
15911600
break
15921601

15931602
return [cmd.unwrap_result() for cmd in stack]
@@ -1649,5 +1658,8 @@ def get_first_exception(self) -> Optional[Tuple[str, Exception]]:
16491658
((n, r) for n, r in self.result.items() if isinstance(r, Exception)), None
16501659
)
16511660

1661+
def get_all_exceptions(self) -> List[Tuple[str, Exception]]:
1662+
return [(n, r) for n, r in self.result.items() if isinstance(r, Exception)]
1663+
16521664
def __repr__(self) -> str:
16531665
return f"[{self.position}] {self.args} ({self.kwargs})"

0 commit comments

Comments
 (0)