OverviewFilesCommitsIssuesDocsReleasesPeers

ollama_semantic_function_calling / ollamatools-new / ollamatools / plugins / errors.py

143 lines · python ref:
"""
Error handling for the OllamaTools plugin system.

This module provides exception classes and utility functions for handling
errors in the OllamaTools plugin system.
"""

import sys
import logging
import traceback
from typing import Dict, Any, Optional

# Configure logging
logger = logging.getLogger(__name__)

class PluginError(Exception):
    """Base class for all plugin-related errors."""
    
    def __init__(self, message, details=None):
        """
        Initialize the error.
        
        Args:
            message: Error message
            details: Optional dictionary with additional error details
        """
        super().__init__(message)
        self.details = details or {}


class PluginNotFoundError(PluginError):
    """Error raised when a plugin is not found."""
    pass


class PluginInitializationError(PluginError):
    """Error raised when a plugin fails to initialize."""
    pass


class PluginDependencyError(PluginError):
    """Error raised when a plugin dependency cannot be satisfied."""
    pass


class PluginExecutionError(PluginError):
    """Error raised when a plugin operation fails during execution."""
    pass


class PluginConfigurationError(PluginError):
    """Error raised when a plugin has invalid configuration."""
    pass


def format_plugin_error(error: PluginError) -> str:
    """
    Format a plugin error into a user-friendly message.
    
    Args:
        error: The plugin error
        
    Returns:
        str: Formatted error message
    """
    message = str(error)
    
    if isinstance(error, PluginNotFoundError):
        return f"Plugin not found: {message}"
    
    if isinstance(error, PluginInitializationError):
        return f"Failed to initialize plugin: {message}"
    
    if isinstance(error, PluginDependencyError):
        dependency = error.details.get("dependency", "unknown")
        return f"Plugin dependency error: {message} (missing: {dependency})"
    
    if isinstance(error, PluginExecutionError):
        plugin = error.details.get("plugin", "unknown")
        operation = error.details.get("operation", "unknown operation")
        return f"Plugin execution error in {plugin}.{operation}: {message}"
    
    if isinstance(error, PluginConfigurationError):
        plugin = error.details.get("plugin", "unknown")
        return f"Invalid configuration for plugin {plugin}: {message}"
    
    # Generic plugin error
    return f"Plugin error: {message}"


def log_plugin_error(error: PluginError, level=logging.ERROR) -> None:
    """
    Log a plugin error with appropriate context.
    
    Args:
        error: The plugin error
        level: Logging level
    """
    # Format the error message
    message = format_plugin_error(error)
    
    # Add details if available
    if error.details:
        details_str = ", ".join(f"{k}={v}" for k, v in error.details.items())
        message = f"{message} [Details: {details_str}]"
    
    # Log the error
    logger.log(level, message, exc_info=True)


def handle_plugin_exception(error: Exception) -> Dict[str, Any]:
    """
    Handle a plugin exception and return error details.
    
    Args:
        error: The exception to handle
        
    Returns:
        Dict[str, Any]: Error details
    """
    error_type = type(error).__name__
    error_message = str(error)
    error_traceback = traceback.format_exc()
    
    # Log the error
    if isinstance(error, PluginError):
        log_plugin_error(error)
    else:
        logger.error(f"Unexpected error: {error_type}: {error_message}", exc_info=True)
    
    # Create error details
    error_details = {
        "error_type": error_type,
        "error_message": error_message,
        "traceback": error_traceback
    }
    
    # Add plugin-specific details
    if isinstance(error, PluginError) and error.details:
        error_details["details"] = error.details
    
    return error_details