1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
|
from __future__ import annotations
from abc import ABC
from abc import abstractmethod
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from types import TracebackType
from typing import Optional
class BasePatcher(ABC):
"""Context manager that logs and prints diagnostic info if an exception
occurs.
"""
def __init__(self, description: str) -> None:
self.description = description
@abstractmethod
def __package_info__(self) -> str:
raise NotImplementedError
def __enter__(self) -> BasePatcher:
return self
def __exit__(
self,
exc_type: Optional[type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[TracebackType],
) -> bool:
if not exc_type:
return True
import sys
import rich
from rich.table import Table
from zabbix_cli.__about__ import __version__
# Rudimentary, but provides enough info to debug and fix the issue
console = rich.console.Console(stderr=True)
console.print_exception()
console.print()
table = Table(
title="Diagnostics",
show_header=False,
show_lines=False,
)
table.add_row(
"[b]Package [/]",
self.__package_info__(),
)
table.add_row(
"[b]zabbix-cli [/]",
__version__,
)
table.add_row(
"[b]Python [/]",
sys.version,
)
table.add_row(
"[b]Platform [/]",
sys.platform,
)
console.print(table)
console.print(f"[bold red]ERROR: Failed to patch {self.description}[/]")
raise SystemExit(1)
def get_patcher(info: str) -> type[BasePatcher]:
"""Returns a patcher for a given package."""
class Patcher(BasePatcher):
def __package_info__(self) -> str:
return info
return Patcher
|