CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cyclopts

Intuitive, easy CLIs based on type hints.

Pending
Overview
Eval results
Files

exceptions.mddocs/

Exception Handling

Comprehensive exception hierarchy for precise error handling and debugging in CLI applications.

Capabilities

Base Exception

Root exception class for all Cyclopts errors.

class CycloptsError(Exception):
    """Base exception class for all Cyclopts errors."""
    
    def __init__(self, message: str = ""):
        """
        Create a Cyclopts exception.
        
        Parameters
        ----------
        message
            Error message
        """

Argument and Parameter Errors

Exceptions related to argument parsing and validation.

class ArgumentOrderError(CycloptsError):
    """Error when positional arguments are in wrong order."""

class MissingArgumentError(CycloptsError):
    """Error when required argument is missing."""

class MixedArgumentError(CycloptsError):
    """Error when incompatible argument types are mixed."""

class RepeatArgumentError(CycloptsError):
    """Error when an argument is repeated inappropriately."""

class UnknownOptionError(CycloptsError):
    """Error when an unknown option is provided."""

class UnusedCliTokensError(CycloptsError):
    """Error when CLI tokens are not consumed during parsing."""

Type Conversion Errors

Exceptions related to type coercion and conversion.

class CoercionError(CycloptsError):
    """Error when type coercion fails."""
    
    def __init__(
        self,
        message: str = "",
        *,
        type_: type | None = None,
        value: Any = None,
        tokens: list[Token] | None = None
    ):
        """
        Create a coercion error.
        
        Parameters
        ----------
        message
            Error message
        type_
            Target type that failed conversion
        value
            Value that failed conversion
        tokens
            Tokens that caused the error
        """

Validation Errors

Exceptions related to value validation.

class ValidationError(CycloptsError):
    """Error during value validation."""
    
    def __init__(
        self,
        message: str = "",
        *,
        value: Any = None,
        validator: Callable | None = None
    ):
        """
        Create a validation error.
        
        Parameters
        ----------
        message
            Error message
        value
            Value that failed validation
        validator
            Validator that rejected the value
        """

Command and Option Errors

Exceptions related to command configuration and option handling.

class CommandCollisionError(CycloptsError):
    """Error when command names collide."""

class InvalidCommandError(CycloptsError):
    """Error when a command is invalid or malformed."""

class CombinedShortOptionError(CycloptsError):
    """Error when combined short options are invalid."""

Documentation Errors

Exceptions related to docstring parsing and help generation.

class DocstringError(CycloptsError):
    """Error parsing function docstrings."""
    
    def __init__(
        self,
        message: str = "",
        *,
        func: Callable | None = None,
        docstring: str | None = None
    ):
        """
        Create a docstring error.
        
        Parameters
        ----------
        message
            Error message
        func
            Function with problematic docstring
        docstring
            The problematic docstring content
        """

Editor Errors

Exceptions related to interactive text editing.

class EditorError(CycloptsError):
    """Base error for editor operations."""

class EditorNotFoundError(EditorError):
    """Error when text editor is not found."""
    
    def __init__(self, editor: str | None = None):
        """
        Create editor not found error.
        
        Parameters
        ----------
        editor
            Editor command that was not found
        """

class EditorDidNotSaveError(EditorError):
    """Error when user did not save in editor."""

class EditorDidNotChangeError(EditorError):
    """Error when user did not change content in editor."""

Usage Examples

Handling Specific Exceptions

from cyclopts import App, run
from cyclopts import ValidationError, CoercionError, MissingArgumentError

app = App()

@app.command
def process_data(input_file: str, threshold: float):
    """Process data with error handling."""
    print(f"Processing {input_file} with threshold {threshold}")

def main():
    try:
        app()
    except ValidationError as e:
        print(f"Validation failed: {e}")
        return 1
    except CoercionError as e:
        print(f"Type conversion failed: {e}")
        return 1  
    except MissingArgumentError as e:
        print(f"Required argument missing: {e}")
        return 1
    except Exception as e:
        print(f"Unexpected error: {e}")
        return 1
    return 0

if __name__ == "__main__":
    exit(main())

Custom Exception Handling

from cyclopts import App, CycloptsError
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

app = App()

@app.command
def risky_operation(count: int):
    """Operation that might fail."""
    if count < 0:
        raise ValueError("Count must be positive")
    print(f"Processing {count} items")

def main():
    try:
        app()
    except CycloptsError as e:
        # Handle all Cyclopts-specific errors
        logger.error(f"CLI error: {e}")
        return 1
    except ValueError as e:
        # Handle application-specific errors
        logger.error(f"Application error: {e}")
        return 2
    except KeyboardInterrupt:
        logger.info("Operation cancelled by user")
        return 130
    return 0

if __name__ == "__main__":
    exit(main())

Editor Error Handling

from cyclopts import App, edit
from cyclopts import EditorError, EditorNotFoundError, EditorDidNotSaveError

app = App()

@app.command
def edit_message():
    """Edit message with comprehensive error handling."""
    try:
        content = edit(
            text="Enter your message here...",
            require_save=True,
            require_change=True
        )
        print("Message created successfully:")
        print(content)
        
    except EditorNotFoundError as e:
        print(f"No editor available: {e}")
        print("Please set the EDITOR environment variable")
        return 1
        
    except EditorDidNotSaveError:
        print("Editor session cancelled - no changes saved")
        return 1
        
    except EditorError as e:
        print(f"Editor error: {e}")
        return 1
    
    return 0

Validation Error with Context

from cyclopts import App, Parameter
from cyclopts.validators import Number
from cyclopts import ValidationError

def validate_even_number(value: int) -> int:
    """Validate that number is even."""
    if value % 2 != 0:
        raise ValidationError(f"Value {value} must be even", value=value)
    return value

app = App()

@app.command
def process_batch(
    batch_size: int = Parameter(
        validator=[Number(min=1, max=1000), validate_even_number],
        help="Batch size (1-1000, must be even)"
    )
):
    """Process data in batches."""
    print(f"Processing with batch size {batch_size}")

def main():
    try:
        app()
    except ValidationError as e:
        print(f"Invalid input: {e}")
        if hasattr(e, 'value') and e.value is not None:
            print(f"Problematic value: {e.value}")
        return 1
    return 0

if __name__ == "__main__":
    exit(main())

Comprehensive Error Handler

from cyclopts import App, CycloptsError
from cyclopts import (
    ValidationError, CoercionError, MissingArgumentError,
    CommandCollisionError, DocstringError
)
import sys

def handle_cyclopts_error(error: CycloptsError) -> int:
    """Handle Cyclopts errors with appropriate messages and exit codes."""
    
    if isinstance(error, ValidationError):
        print(f"❌ Validation Error: {error}", file=sys.stderr)
        return 2
        
    elif isinstance(error, CoercionError):
        print(f"❌ Type Error: {error}", file=sys.stderr)
        return 3
        
    elif isinstance(error, MissingArgumentError):
        print(f"❌ Missing Argument: {error}", file=sys.stderr)
        return 4
        
    elif isinstance(error, CommandCollisionError):
        print(f"❌ Configuration Error: {error}", file=sys.stderr)
        return 5
        
    elif isinstance(error, DocstringError):
        print(f"❌ Documentation Error: {error}", file=sys.stderr)
        return 6
        
    else:
        print(f"❌ CLI Error: {error}", file=sys.stderr)
        return 1

app = App()

@app.command
def example(value: int):
    """Example command."""
    print(f"Value: {value}")

def main():
    try:
        app()
        return 0
    except CycloptsError as e:
        return handle_cyclopts_error(e)
    except KeyboardInterrupt:
        print("\n⚠️  Operation cancelled", file=sys.stderr)
        return 130
    except Exception as e:
        print(f"💥 Unexpected error: {e}", file=sys.stderr)
        return 1

if __name__ == "__main__":
    exit(main())

Install with Tessl CLI

npx tessl i tessl/pypi-cyclopts

docs

advanced-features.md

arguments-parameters.md

configuration.md

core-app.md

exceptions.md

index.md

types-validation.md

tile.json