fix: never crash on a bad level= string (v0.1.1)

_level_value used logging.getLevelName(name), which returns the string 'Level XXX'
for an unknown name; that string then reached setLevel() and raised ValueError,
violating the 'never crashes the app over logging' contract. validate the result is
an int and fall back to INFO otherwise.

verified: level='BOGUS' -> INFO (no crash); 'DEBUG' and int levels still honored.
Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
disqualifier 2026-06-27 21:49:20 -04:00
parent c6efee59c1
commit 84e1744d6f
3 changed files with 8 additions and 3 deletions

View File

@ -4,7 +4,7 @@ build-backend = "hatchling.build"
[project]
name = "log_setup"
version = "0.1.0"
version = "0.1.1"
description = "stdlib app-entry-point logging setup: live run.log, rotation, gzip, retention, consistent format"
requires-python = ">=3.10"
dependencies = []

View File

@ -19,4 +19,4 @@ from .setup import setup_logging
__all__ = ["setup_logging"]
__version__ = "0.1.0"
__version__ = "0.1.1"

View File

@ -28,7 +28,12 @@ def _level_value(level: Union[int, str]) -> int:
"""coerce a level name or int to a logging level int (defaults to INFO)"""
if isinstance(level, int):
return level
return logging.getLevelName(str(level).upper()) if isinstance(level, str) else logging.INFO
if not isinstance(level, str):
return logging.INFO
resolved = logging.getLevelName(level.upper())
# getLevelName returns the string "Level XXX" for an unknown name, which
# setLevel then rejects — never crash the app over a bad level, fall back to INFO
return resolved if isinstance(resolved, int) else logging.INFO
def _clear_owned(root: logging.Logger) -> None: