Skip to content

Commit

Permalink
Add retry_if_exception_message and complement
Browse files Browse the repository at this point in the history
This is just a quick draft to get ideas on the table.

Open to suggestions on default logic, naming or copying this into your
own branch and opening a separate MR.
  • Loading branch information
Brian-Williams committed Jul 12, 2018
1 parent 30fff9d commit 8d19588
Showing 1 changed file with 47 additions and 1 deletion.
48 changes: 47 additions & 1 deletion tenacity/retry.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
# limitations under the License.

import abc
import re
from functools import wraps

import six

Expand Down Expand Up @@ -86,7 +88,7 @@ def __call__(self, attempt):
# always retry if no exception was raised
if not attempt.failed:
return True
return self.predicate(attempt.exception())
return self.predicate(str(attempt.exception()))

This comment has been minimized.

Copy link
@Brian-Williams

Brian-Williams Jul 13, 2018

Author Owner

This is a typo that would break this class if merged.



class retry_if_result(retry_base):
Expand All @@ -111,6 +113,50 @@ def __call__(self, attempt):
return not self.predicate(attempt.result())


class retry_if_exception_message(retry_base):
"""Retries if an exception message equals or matches."""

def __init__(self, message=None, match=None, require_exception=False):
if message and match:
raise TypeError("retry_if_exception_message() takes either 'message' or 'match', not both")
self.predicate = self._predicate_factory(message, match)
self.require_exception = require_exception

def _predicate_factory(self, message, match):
if message:
def message_fnc(exception_message):
return message == str(exception_message)
return message_fnc
elif match:
prog = re.compile(match)

def match_fnc(exception_message):
return prog.match(str(exception_message))
return match_fnc
else:
raise TypeError("retry_if_exception_message() missing 1 required argument 'message' or 'match'")

def __call__(self, attempt):
if not attempt.failed:
if self.require_exception:
raise RuntimeError("No exception to get errormessage from")
return True
return self.predicate(str(attempt.exception()))


class retry_if_not_exception_message(retry_if_exception_message):
"""Retries until an exception message equals or matches."""

def _predicate_factory(self, *args, **kwargs):
inverted_predicate = super(retry_if_not_exception_message, self)._predicate_factory(*args, **kwargs)

@wraps(inverted_predicate)
def predicate(*args_, **kwargs_):
return not inverted_predicate(*args_, **kwargs_)

return predicate


class retry_any(retry_base):
"""Retries if any of the retries condition is valid."""

Expand Down

0 comments on commit 8d19588

Please sign in to comment.