Skip to content

Commit ea2a464

Browse files
strategy/common: introduce never_retry decorator
Introduce a decorator meant to decorate the strategy's transition() and force() methods. It stores the original exception in the broken attribute and raises a StrategyError from it. All subsequent calls to the decorated method will lead to the same exception. This prevents a strategy from subsequent use after an exception happened, thus no cascading errors can happen. Signed-off-by: Bastian Krause <[email protected]>
1 parent 92a9541 commit ea2a464

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

labgrid/strategy/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .common import Strategy, StrategyError
1+
from .common import Strategy, StrategyError, never_retry
22
from .bareboxstrategy import BareboxStrategy
33
from .shellstrategy import ShellStrategy
44
from .ubootstrategy import UBootStrategy

labgrid/strategy/common.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
1+
import functools
2+
13
import attr
24

35
from ..binding import BindingError
46
from ..driver import Driver
57

68

9+
def never_retry(func):
10+
"""
11+
Strategy method decorator storing the original exception in strategy.broken and raising a
12+
StrategyError from it. All subsequent calls to the decorated method will lead to the same
13+
exception.
14+
"""
15+
@functools.wraps(func)
16+
def wrapper(self, *args, **kwargs):
17+
if self.broken:
18+
# a previous call broke the strategy, raise the original exception again
19+
raise StrategyError(f"{self.__class__.__name__} is in broken state") from self.broken
20+
21+
try:
22+
return func(self, *args, **kwargs)
23+
except Exception as e:
24+
# store original exception and raise StrategyError from it
25+
self.broken = e
26+
raise StrategyError(f"{self.__class__.__name__} is in broken state") from self.broken
27+
28+
return wrapper
29+
30+
731
@attr.s(eq=False)
832
class StrategyError(Exception):
933
msg = attr.ib(validator=attr.validators.instance_of(str))

0 commit comments

Comments
 (0)