Open
Description
hi
so in my testings i have found that, possibly, omit exception lacks generator support (e.g: iter_keys and sscan_iter)
this is becaouse omit_exception calls the method https://github.com/jazzband/django-redis/blob/master/django_redis/cache.py#L29 and catches errors
but, calling a generator doesn't raise any errors, it'll only error once you iterate over it
as a simple example you can run:
>>> def my_gen():
... for i in range(10):
... yield
... raise
...
>>> my_gen()
<generator object my_gen at 0x7f8fc7a56800>
>>> for i in my_gen():
... print(1)
...
1
Traceback (most recent call last):
File "<python-input-4>", line 1, in <module>
for i in my_gen():
~~~~~~^^
File "<python-input-2>", line 4, in my_gen
raise
RuntimeError: No active exception to reraise
anyway the way i went to fix it was with something like this:
def omit_exception(method: Callable | None = None, return_value: Any | None = None):
"""
Simple decorator that intercepts connection
errors and ignores these if settings specify this.
"""
if method is None:
return functools.partial(omit_exception, return_value=return_value)
@functools.wraps(method)
def _decorator(self, *args, **kwargs):
try:
return method(self, *args, **kwargs)
except ConnectionInterrupted as e:
if getattr(self, "_ignore_exceptions", None) or getattr(
self._backend, "_ignore_exceptions"
):
if getattr(self, "_log_ignored_exceptions", None) or getattr(
self._backend, "_log_ignored_exceptions"
):
logger = getattr(self, "logger", None) or getattr(
self._backend, "logger"
)
logger.exception("Exception ignored")
return return_value
raise e.__cause__ # noqa: B904
@functools.wraps(method)
def _generator_decorator(self, *args, **kwargs):
try:
for item in method(self, *args, **kwargs):
yield item
except ConnectionInterrupted as e:
if getattr(self, "_ignore_exceptions", None) or getattr(
self._backend, "_ignore_exceptions"
):
if getattr(self, "_log_ignored_exceptions", None) or getattr(
self._backend, "_log_ignored_exceptions"
):
logger = getattr(self, "logger", None) or getattr(
self._backend, "logger"
)
logger.exception("Exception ignored")
return return_value
raise e.__cause__
wrapper = _generator_decorator if inspect.isgeneratorfunction(method) else _decorator
let me know if this is ok with you , i can open a PR, or you can commit it as you wish