From c0850f1ff280d8a7e9fee027ad633db7abb0ad75 Mon Sep 17 00:00:00 2001 From: sleep Date: Wed, 22 Jan 2025 16:01:55 +0100 Subject: [PATCH] Rewrote the error handler for better error message clarity --- src/armonik_cli/core/decorators.py | 41 ++++++++++++++++++++++-------- src/armonik_cli/exceptions.py | 24 +++++++++++++++++ 2 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/armonik_cli/core/decorators.py b/src/armonik_cli/core/decorators.py index 6452571..7681f29 100644 --- a/src/armonik_cli/core/decorators.py +++ b/src/armonik_cli/core/decorators.py @@ -4,7 +4,15 @@ import rich_click as click from armonik_cli.core.console import console -from armonik_cli.exceptions import NotFoundError, InternalError, InternalArmoniKError +from armonik_cli.exceptions import ( + AlreadyExistsError, + ArmoniKCLIError, + DeadlineExceededError, + InvalidArgumentError, + NotFoundError, + InternalError, + InternalArmoniKError, +) def error_handler(func=None): @@ -23,27 +31,38 @@ def error_handler(func=None): @wraps(func) def wrapper(*args, **kwargs): + debug_mode = kwargs.get("debug", False) try: return func(*args, **kwargs) - except click.ClickException: - raise except grpc.RpcError as err: status_code = err.code() - error_details = f"{err.details()}." - + error_details = f"{err.details()} (gRPC Code: {status_code.name})." + if debug_mode: + console.print_exception() if status_code == grpc.StatusCode.NOT_FOUND: raise NotFoundError(error_details) + elif status_code == grpc.StatusCode.ALREADY_EXISTS: + raise AlreadyExistsError(f"Resource already exists: {error_details}") + elif status_code == grpc.StatusCode.INVALID_ARGUMENT: + raise InvalidArgumentError(f"Invalid argument provided: {error_details}") + elif status_code == grpc.StatusCode.DEADLINE_EXCEEDED: + raise DeadlineExceededError(f"Request deadline exceeded: {error_details}") elif status_code == grpc.StatusCode.INTERNAL: - raise InternalArmoniKError(f"An internal exception has occured:\n{error_details}") + raise InternalArmoniKError(f"An internal exception occurred:\n{error_details}") elif status_code == grpc.StatusCode.UNKNOWN: - raise InternalArmoniKError(f"An unknown exception has occured:\n{error_details}") + raise InternalArmoniKError(f"An unknown exception occurred:\n{error_details}") + else: + raise InternalError(f"An unhandled gRPC error occurred: {error_details}") + except ArmoniKCLIError as e: + if debug_mode: + console.print_exception() else: - raise InternalError("An internal fatal error occured.") - except Exception: - if "debug" in kwargs and kwargs["debug"]: + e.show() + except Exception as e: + if debug_mode: console.print_exception() else: - raise InternalError("An internal fatal error occured.") + raise InternalError(f"An internal fatal error occurred: {str(e)}") return wrapper diff --git a/src/armonik_cli/exceptions.py b/src/armonik_cli/exceptions.py index 5de1f12..563779a 100644 --- a/src/armonik_cli/exceptions.py +++ b/src/armonik_cli/exceptions.py @@ -1,4 +1,6 @@ import rich_click as click +from rich.panel import Panel +from rich import print class ArmoniKCLIError(click.ClickException): @@ -7,6 +9,10 @@ class ArmoniKCLIError(click.ClickException): def __init__(self, message: str) -> None: super().__init__(message) + def show(self, file=None): + """Override to display errors in a cleaner format.""" + print(Panel(self.format_message(), title="Error", style="red")) + class InternalError(ArmoniKCLIError): """Error raised when an unknown internal error occured.""" @@ -18,3 +24,21 @@ class InternalArmoniKError(ArmoniKCLIError): class NotFoundError(ArmoniKCLIError): """Error raised when a given object of the API is not found.""" + + +class InvalidArgumentError(ArmoniKCLIError): + """Error raised when gRPC client gets specified an invalid argument.""" + + pass + + +class AlreadyExistsError(ArmoniKCLIError): + """Error raised when attempting to create an entity via gRPC that already exists""" + + pass + + +class DeadlineExceededError(ArmoniKCLIError): + """Error raised when deadline expires before operation could complete.""" + + pass