"""
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