From 588b997d8c517b7f26269c5c984fdb8616e955ef Mon Sep 17 00:00:00 2001 From: pierrocknroll Date: Tue, 29 Apr 2025 12:00:33 +0200 Subject: [PATCH] :goal_net: Improve error handling --- src/logger/errors.py | 20 ++++++++++++++++++++ src/logger/loggable_mixin.py | 5 +++-- src/logger/loglevel.py | 8 ++++---- tests/logger/loggable_mixin_test.py | 3 ++- tests/logger/loglevel_test.py | 3 ++- tests/logger/loguru_test.py | 3 ++- 6 files changed, 33 insertions(+), 9 deletions(-) create mode 100644 src/logger/errors.py diff --git a/src/logger/errors.py b/src/logger/errors.py new file mode 100644 index 0000000..a978665 --- /dev/null +++ b/src/logger/errors.py @@ -0,0 +1,20 @@ +class LoggerError(Exception): + """Base class for package exceptions.""" + + +class UnknownLogLevelError(LoggerError): + """Raised when a specified log level doesn't match any known log level.""" + + def __init__(self, invalid_value: str, valid_values: list) -> None: + """Raise the error with correct message.""" + super().__init__( + f"Invalid log level '{invalid_value}'. Must be one of: {valid_values}", + ) + + +class LoggerNotSetError(LoggerError): + """Raised when a logger is not set on the application.""" + + def __init__(self) -> None: + """Raise the error with correct message.""" + super().__init__("Logger not set") diff --git a/src/logger/loggable_mixin.py b/src/logger/loggable_mixin.py index 9a7ca74..4121c78 100644 --- a/src/logger/loggable_mixin.py +++ b/src/logger/loggable_mixin.py @@ -1,4 +1,5 @@ from .contract import LoggerContract +from .errors import LoggerNotSetError class LoggableMixin: @@ -16,10 +17,10 @@ def logger(self) -> LoggerContract: The configured logger instance. Raises: - RuntimeError: If logger has not been set. + LoggerNotSetError: If logger has not been set. """ if self._logger is None: - raise RuntimeError("Logger not set") + raise LoggerNotSetError return self._logger @logger.setter diff --git a/src/logger/loglevel.py b/src/logger/loglevel.py index 06fd4d2..c784799 100644 --- a/src/logger/loglevel.py +++ b/src/logger/loglevel.py @@ -2,6 +2,8 @@ from enum import IntEnum from typing import Self +from .errors import UnknownLogLevelError + class LogLevel(IntEnum): """Represents the different log levels.""" @@ -23,12 +25,10 @@ def from_str(cls, value: str) -> Self: LogLevel enum value. Raises: - ValueError: If the string doesn't match any log level. + UnknownLogLevelError: If the string doesn't match any log level. """ try: return cls[value.upper()] except KeyError as e: valid_values = [e.name for e in cls] - raise ValueError( - f"Invalid log level '{value}'. Must be one of: {valid_values}", - ) from e + raise UnknownLogLevelError(value, valid_values) from e diff --git a/tests/logger/loggable_mixin_test.py b/tests/logger/loggable_mixin_test.py index f7394bc..dd1443e 100644 --- a/tests/logger/loggable_mixin_test.py +++ b/tests/logger/loggable_mixin_test.py @@ -2,6 +2,7 @@ import pytest +from src.logger.errors import LoggerNotSetError from src.logger.loggable_mixin import LoggableMixin @@ -27,7 +28,7 @@ def test_logger_not_set(self, loggable: LoggableMixin) -> None: Args: loggable: Fresh LoggableMixin instance without a logger set """ - with pytest.raises(RuntimeError, match="Logger not set"): + with pytest.raises(LoggerNotSetError, match="Logger not set"): _ = loggable.logger def test_logger_set(self, loggable: LoggableMixin, mock_logger: Mock) -> None: diff --git a/tests/logger/loglevel_test.py b/tests/logger/loglevel_test.py index 99790fd..0598c9a 100644 --- a/tests/logger/loglevel_test.py +++ b/tests/logger/loglevel_test.py @@ -1,5 +1,6 @@ import pytest +from src.logger.errors import UnknownLogLevelError from src.logger.loglevel import LogLevel @@ -29,5 +30,5 @@ def test_from_str_invalid(self) -> None: - The error message contains "Invalid log level" to help with debugging - The validation prevents incorrect string values from being accepted """ - with pytest.raises(ValueError, match="Invalid log level"): + with pytest.raises(UnknownLogLevelError, match="Invalid log level"): LogLevel.from_str("INVALID") diff --git a/tests/logger/loguru_test.py b/tests/logger/loguru_test.py index dc1c236..8cc1615 100644 --- a/tests/logger/loguru_test.py +++ b/tests/logger/loguru_test.py @@ -91,7 +91,8 @@ def test_exception_log( - Additional context is preserved """ try: - raise ValueError("Sample exception") # noqa: TRY301 + msg = "Sample exception" + raise ValueError(msg) # noqa: TRY301 except ValueError as exc: loguru_logger.exception( "An error occurred",