Skip to content

v0.1.29 - CLI Exception Handling Refactoring (2025-12-07)

What Changed?

This release refactors CLI command exception handling into a reusable decorator. The handle_kazunoko_errors decorator centralizes the handling of common exceptions (CommandTimeout, ResponseTimeout, KazunokoError), eliminating 30+ lines of duplicate try-except blocks across CLI commands. The refactoring improves code maintainability, consistency, and testability while preserving all existing functionality.


What's New

Main Feature: Exception Handling Decorator Pattern

What it does: The handle_kazunoko_errors decorator provides a DRY (Don't Repeat Yourself) approach to exception handling for CLI commands. It catches common Kazunoko exceptions, displays user-friendly error messages with colored output, and exits with code 1 on error. The decorator uses functools.wraps to preserve function metadata, ensuring full compatibility with Typer's command registration and help generation.

How to use it:

from kazunoko.cli import handle_kazunoko_errors
import typer

@app.command()
@handle_kazunoko_errors
def my_command(arg: str) -> None:
    """My CLI command"""
    # Your business logic here
    # Exceptions are automatically handled by the decorator

Code example:

Before (v0.1.28):

@app.command()
def query(command: str, ...):
    try:
        # Command logic
        pass
    except CommandTimeout:
        console.print("[red]✗ Command timeout: device did not respond[/red]")
        raise typer.Exit(code=1)
    except ResponseTimeout:
        console.print("[red]✗ Response timeout: no data received[/red]")
        raise typer.Exit(code=1)
    except KazunokoError as e:
        console.print(f"[red]✗ Error: {e}[/red]")
        raise typer.Exit(code=1)

After (v0.1.29):

@app.command()
@handle_kazunoko_errors
def query(command: str, ...):
    # Command logic without exception handling
    pass

Installation

Quick Start

# Get the release
git checkout v0.1.29

# Setup
uv sync

# Run CLI
uv run kazunoko --help

What's Different from the Last Version?

✅ Added

  • handle_kazunoko_errors decorator: Centralizes exception handling for CLI commands
  • Uses functools.wraps to preserve function metadata for Typer compatibility
  • Comprehensive docstring with decorator usage explanation

🔧 Changed

  • query command: Now uses @handle_kazunoko_errors decorator
  • status command: Now uses @handle_kazunoko_errors decorator
  • threshold command: Now uses @handle_kazunoko_errors decorator (retains input validation)
  • reset command: Now uses @handle_kazunoko_errors decorator
  • generate command: Removed duplicate KeyboardInterrupt handling for consistency
  • Exception handling is now centralized in one decorator instead of spread across 4+ commands

🐛 Fixed

  • Eliminated code duplication in exception handling across multiple CLI commands
  • Removed duplicate KeyboardInterrupt handlers in generate command (line 388 and 403)

Is It Safe to Upgrade?

Backward Compatible: Yes

Impact on existing users:

  • CLI users see no functional change (commands work exactly the same)
  • All error messages remain identical
  • Command metadata (help text, arguments) fully preserved via functools.wraps
  • Library users are unaffected (CLI changes only)
  • Internal exception handling logic is identical; only organization has changed

Tests Passed

  • ✅ Builds without errors (Ruff lint: 100% pass)
  • ✅ Type checking compatible (mypy - decorator typing verified)
  • ✅ All CLI commands work correctly with decorator applied:
  • kazunoko query GET_STATUS --mock
  • kazunoko status --mock
  • kazunoko threshold "1:300;2:300;3:300" --mock
  • kazunoko reset --mock
  • kazunoko generate random --count 3
  • ✅ Typer help generation works with decorated functions
  • ✅ Function metadata preserved (__name__, __doc__) via wraps

Code Changes Summary

Files Modified: 1

  • src/kazunoko/cli.py - Added handle_kazunoko_errors decorator, applied to 4 commands, removed duplicate exception handlers

Lines Changed: 32 added, 44 removed (12 net reduction)

Imports Added:

  • from functools import wraps
  • from typing import Callable, Optional (added Callable)

Release Details

  • Date: 2025-12-07
  • Version: v0.1.29
  • Files Changed: 1
  • Commits:
  • ab4dc9c - refactor: extract common exception handling into decorator

Next Steps

Future improvements to consider:

  • Extract other common patterns from CLI commands into reusable decorators
  • Add logging decorator for command execution tracking
  • Consider decorator composition for advanced command features
  • Expand test coverage for decorator behavior with different exception types