diff --git a/src/zinolib/controllers/zino1.py b/src/zinolib/controllers/zino1.py index ef7b5dc..5b20ef5 100644 --- a/src/zinolib/controllers/zino1.py +++ b/src/zinolib/controllers/zino1.py @@ -66,7 +66,7 @@ """ from datetime import datetime, timezone -from typing import Iterable, List, TypedDict, Optional, Set +from typing import Dict, Iterable, List, TypedDict, Optional, Set import logging from .base import EventManager @@ -74,6 +74,7 @@ from ..event_types import EventType, Event, HistoryEntry, LogEntry, AdmState from ..event_types import PortStateEvent from ..ritz import ZinoError, ritz, notifier +from ..utils import log_exception_with_params __all__ = [ @@ -248,7 +249,8 @@ def get_attrlist(request, event_id: int): return request.get_raw_attributes(event_id) @classmethod - def attrlist_to_attrdict(cls, attrlist: Iterable[str]): + @log_exception_with_params(LOG) + def attrlist_to_attrdict(cls, attrlist: Iterable[str]) -> Dict[str, str]: """Translate a wire protocol dump of a single event The dump is a list of lines of the format: @@ -290,6 +292,7 @@ def get_history(request, event_id: int): return request.get_raw_history(event_id).data @classmethod + @log_exception_with_params(LOG) def parse_response(cls, history_data: Iterable[str]) -> list[HistoryDict]: """ Input: @@ -357,6 +360,7 @@ def get_log(request, event_id: int) -> list[str]: return request.get_raw_log(event_id).data @staticmethod + @log_exception_with_params(LOG) def parse_response(log_data: Iterable[str]) -> list[LogDict]: """ Input: diff --git a/src/zinolib/utils.py b/src/zinolib/utils.py index 79b1761..dca5819 100644 --- a/src/zinolib/utils.py +++ b/src/zinolib/utils.py @@ -1,4 +1,6 @@ +import functools import hashlib +from typing import Any __all__ = [ @@ -56,3 +58,26 @@ def generate_authtoken(challenge, password): raw_token = "%s %s" % (challenge, password) token = hashlib.sha1(raw_token.encode("UTF-8")).hexdigest() return token + + +def log_exception_with_params(logger, reraise=True, return_value=None): + """Log the params and exception if the wrapped function fails + + If ``reraise`` is False, return ``return_value`` instead of reraising the + exception. + """ + def inner(function): + @functools.wraps(function) + def wrapper(*args, **kwargs): + try: + result = function(*args, **kwargs) + return result + except Exception as e: + params = f'args={args} kwargs={kwargs}' + funcname = function.__name__ + logger.exception(f'"{funcname}" failed with: {params}\n{e}') + if reraise: + raise + return return_value + return wrapper + return inner