Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom logger name for log_if_fails #81

Merged
merged 1 commit into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- Feat: Support custom logger names for `log_if_fails` decorator

## [0.4.1] - 2024-2-1

- Fix: Fix submodule usage detection when installed as an embedded dependency
Expand Down
47 changes: 30 additions & 17 deletions tools/decorations.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,48 @@
__email__ = "[email protected]"
__revision__ = "$Format:%H$"

from typing import Any, Callable
from typing import Any, Callable, Optional

from .exceptions import QgsPluginException
from .i18n import tr
from .messages import MsgBar
from .messages import MessageBarLogger
from .tasks import FunctionTask


def log_if_fails(fn: Callable) -> Callable:
def log_if_fails(
fn: Optional[Callable] = None, /, *, logger_name: str = __name__
) -> Callable:
"""
Use this as a decorator with functions and methods that
might throw uncaught exceptions.
"""
from functools import wraps

@wraps(fn)
def wrapper(*args: Any, **kwargs: Any) -> None: # noqa: ANN001
try:
# Qt injects False into some signals
if args[1:] != (False,):
fn(*args, **kwargs)
else:
fn(*args[:-1], **kwargs)
except QgsPluginException as e:
MsgBar.exception(e, **e.bar_msg, stack_info=True)
except Exception as e:
MsgBar.exception(tr("Unhandled exception occurred"), e, stack_info=True)

return wrapper
# caller is at depth 3 (MessageBarLogger log call, this function, actual call)
message_bar = MessageBarLogger(logger_name, stack_level=3)

def decorator(fn: Callable) -> Callable:
@wraps(fn)
def wrapper(*args: Any, **kwargs: Any) -> None: # noqa: ANN001
try:
# Qt injects False into some signals
if args[1:] != (False,):
fn(*args, **kwargs)
else:
fn(*args[:-1], **kwargs)
except QgsPluginException as e:
message_bar.exception(e, **e.bar_msg, stack_info=True)
except Exception as e:
message_bar.exception(
tr("Unhandled exception occurred"), e, stack_info=True
)

return wrapper

if fn is None:
return decorator

return decorator(fn)


def taskify(fn: Callable) -> Callable:
Expand Down
12 changes: 9 additions & 3 deletions tools/messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ class MessageBarLogger:
Setup with a logger name that has a message bar set.
"""

def __init__(self, logger_name: str) -> None:
def __init__(self, logger_name: str, stack_level: int = 2) -> None:
self._logger = logging.getLogger(logger_name)
self._logger_kwargs: Dict[str, Any] = (
{}
if sys.version_info.major == 3 and sys.version_info.minor < 8
else {"stacklevel": 2}
else {"stacklevel": stack_level}
)

def info(
Expand Down Expand Up @@ -148,10 +148,16 @@ def exception(
:param exc_info: Exception of handled exception for capturing traceback
:param stack_info: Whether to include stack info
"""
self._logger.exception(
# for some reason using logger.exception will essentially have extra stack level
# even though its not visible on the printed stack (possibly due to exception
# being a simple helper which calls error internally). use plain error here to
# have same effective stacklevel on both actual log records. possibly related
# https://github.com/python/cpython/issues/89334 has been fixed in 3.11+
self._logger.error(
str(message),
extra=bar_msg(details, duration, success),
stack_info=stack_info,
exc_info=True,
**self._logger_kwargs,
)
if details != "":
Expand Down
Loading