Coverage for src / ezqt_app / utils / diagnostics.py: 85.00%
16 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-26 07:07 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-03-26 07:07 +0000
1# ///////////////////////////////////////////////////////////////
2# UTILS.DIAGNOSTICS - Unified warning helpers
3# Project: ezqt_app
4# ///////////////////////////////////////////////////////////////
6"""Helpers to standardize logger/printer warning outputs."""
8from __future__ import annotations
10# ///////////////////////////////////////////////////////////////
11# IMPORTS
12# ///////////////////////////////////////////////////////////////
13# Third-party imports
14from ezpl import Ezpl
16# Local imports
17from .printer import get_printer
20# ///////////////////////////////////////////////////////////////
21# FUNCTIONS
22# ///////////////////////////////////////////////////////////////
23def _format_log_message(code: str, message: str, error: Exception | None = None) -> str:
24 """Build a codified warning line for file logs."""
25 if error is None:
26 return f"[{code}] {message}"
27 return f"[{code}] {message}: {error}"
30def warn_tech(code: str, message: str, error: Exception | None = None) -> None:
31 """Log a technical warning (logger only, no console output)."""
32 Ezpl().get_logger().warning(
33 _format_log_message(code=code, message=message, error=error)
34 )
37def warn_user(
38 code: str,
39 user_message: str,
40 *,
41 log_message: str | None = None,
42 error: Exception | None = None,
43 show_error_details_in_verbose: bool = True,
44) -> None:
45 """Emit a user-facing warning and a codified log warning.
47 Console output should stay concise and readable for end users,
48 while logs keep technical details and stable error codes.
49 """
50 Ezpl().get_logger().warning(
51 _format_log_message(
52 code=code,
53 message=log_message or user_message,
54 error=error,
55 )
56 )
57 get_printer().warning(user_message)
59 if error is not None and show_error_details_in_verbose: 59 ↛ 60line 59 didn't jump to line 60 because the condition on line 59 was never true
60 get_printer().verbose_msg(f"[{code}] {type(error).__name__}: {error}")
63def info_user(message: str) -> None:
64 """Emit a user-facing informational message (console only)."""
65 get_printer().info(message)