2020-05-08 23:35:25 +02:00
|
|
|
"""
|
|
|
|
An error logging decorator.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import logging
|
2020-05-12 21:02:41 +02:00
|
|
|
from typing import Any, Callable, TypeVar, cast
|
2020-05-08 23:35:25 +02:00
|
|
|
|
2020-05-08 23:47:05 +02:00
|
|
|
from rich.console import Console
|
|
|
|
|
2020-05-09 00:00:21 +02:00
|
|
|
from .logging import PrettyLogger
|
2020-05-08 23:35:25 +02:00
|
|
|
|
|
|
|
LOGGER = logging.getLogger(__name__)
|
|
|
|
PRETTY = PrettyLogger(LOGGER)
|
|
|
|
|
|
|
|
|
2020-05-09 00:00:21 +02:00
|
|
|
class FatalException(Exception):
|
|
|
|
"""
|
|
|
|
A fatal exception occurred. Recovery is not possible.
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
2020-05-12 21:02:41 +02:00
|
|
|
TFun = TypeVar('TFun', bound=Callable[..., Any])
|
|
|
|
|
|
|
|
|
|
|
|
def swallow_and_print_errors(function: TFun) -> TFun:
|
2020-05-08 23:35:25 +02:00
|
|
|
"""
|
|
|
|
Decorates a function, swallows all errors, logs them and returns none if one occurred.
|
|
|
|
"""
|
|
|
|
def inner(*args: Any, **kwargs: Any) -> Any:
|
|
|
|
# pylint: disable=broad-except
|
|
|
|
try:
|
|
|
|
return function(*args, **kwargs)
|
|
|
|
except FatalException as error:
|
|
|
|
PRETTY.error(str(error))
|
|
|
|
return None
|
|
|
|
except Exception as error:
|
|
|
|
Console().print_exception()
|
|
|
|
return None
|
2020-05-12 21:02:41 +02:00
|
|
|
return cast(TFun, inner)
|
2021-04-13 11:32:55 +02:00
|
|
|
|
|
|
|
|
|
|
|
def retry_on_io_exception(max_retries: int, message: str) -> Callable[[TFun], TFun]:
|
|
|
|
"""
|
|
|
|
Decorates a function and retries it on any exception until the max retries count is hit.
|
|
|
|
"""
|
|
|
|
def retry(function: TFun) -> TFun:
|
|
|
|
def inner(*args: Any, **kwargs: Any) -> Any:
|
|
|
|
for i in range(0, max_retries):
|
|
|
|
# pylint: disable=broad-except
|
|
|
|
try:
|
|
|
|
return function(*args, **kwargs)
|
|
|
|
except IOError as error:
|
|
|
|
PRETTY.warning(f"Error duing operation '{message}': {error}")
|
|
|
|
PRETTY.warning(
|
|
|
|
f"Retrying operation '{message}'. Remaining retries: {max_retries - 1 - i}")
|
|
|
|
return cast(TFun, inner)
|
|
|
|
return retry
|