Source code for cloudos_cli.utils.cli_helpers

"""CLI helper utilities for debug mode and exception handling."""

import rich_click as click
import sys
import logging
from rich.console import Console
from cloudos_cli.logging.logger import setup_logging

# Global debug state
_global_debug = False


[docs] def custom_exception_handler(exc_type, exc_value, exc_traceback): """Custom exception handler that respects debug mode""" console = Console(stderr=True) # Initialise logger debug_mode = '--debug' in sys.argv setup_logging(debug_mode) logger = logging.getLogger("CloudOS") if get_debug_mode(): logger.error(exc_value, exc_info=exc_value) console.print("[yellow]Debug mode: showing full traceback[/yellow]") sys.__excepthook__(exc_type, exc_value, exc_traceback) else: # Extract a clean error message if hasattr(exc_value, 'message'): error_msg = exc_value.message elif str(exc_value): error_msg = str(exc_value) else: error_msg = f"{exc_type.__name__}" logger.error(exc_value) console.print(f"[bold red]Error: {error_msg}[/bold red]") # For network errors, give helpful context if 'HTTPSConnectionPool' in str(exc_value) or 'Max retries exceeded' in str(exc_value): console.print("[yellow]Tip: This appears to be a network connectivity issue. Please check your internet connection and try again.[/yellow]")
[docs] def pass_debug_to_subcommands(group_cls=click.RichGroup): """Custom Group class that passes --debug option to all subcommands""" class DebugGroup(group_cls): def add_command(self, cmd, name=None): # Add debug option to the command if it doesn't already have it if isinstance(cmd, (click.Command, click.Group)): has_debug = any(param.name == 'debug' for param in cmd.params) if not has_debug: debug_option = click.Option( ['--debug'], is_flag=True, help='Show detailed error information and tracebacks', is_eager=True, expose_value=False, callback=self._debug_callback ) cmd.params.insert(-1, debug_option) # Insert at the end for precedence super().add_command(cmd, name) def _debug_callback(self, ctx, param, value): """Callback to handle debug flag""" global _global_debug if value: _global_debug = True ctx.meta['debug'] = True else: ctx.meta['debug'] = False return value return DebugGroup
[docs] def get_debug_mode(): """Get current debug mode state""" return _global_debug
[docs] def setup_debug(ctx, param, value): """Setup debug mode globally and in context""" global _global_debug _global_debug = value if value: ctx.meta['debug'] = True else: ctx.meta['debug'] = False return value