UNPKG

@dorothywebb/any-browser-mcp

Version:

Any Browser MCP - Launch Chrome with your actual data in debug mode for comprehensive browser automation

357 lines 13.5 kB
/** * Comprehensive Error Handling System for Any Browser MCP * * @fileoverview Provides specific error types for different failure scenarios with detailed * messages, recovery suggestions, and comprehensive error context. This system enables * better debugging and user guidance when issues occur. * * @example * ```typescript * import { ErrorFactory, ErrorCode } from './errors.js'; * * // Create specific error types * const connectionError = ErrorFactory.createConnectionError( * 'Failed to connect to browser', * { operation: 'checkBrowserAvailability', details: { port: 9223 } } * ); * * // Get formatted error message with recovery actions * console.error(connectionError.getFormattedMessage()); * * // Convert to JSON for logging * console.log(JSON.stringify(connectionError.toJSON(), null, 2)); * ``` * * @category Error Handling */ /** * Enumeration of all possible error codes in the Any Browser MCP system. * * @description Each error code represents a specific type of failure that can occur * during browser automation operations. These codes help categorize errors for * better handling and user guidance. * * @example * ```typescript * if (error.code === ErrorCode.CONNECTION_FAILED) { * // Handle connection-specific errors * console.log('Browser connection failed'); * } else if (error.code === ErrorCode.TOOL_EXECUTION_FAILED) { * // Handle tool execution errors * console.log('Browser tool failed to execute'); * } * ``` */ export var ErrorCode; (function (ErrorCode) { // Connection Errors /** Browser connection failed to establish */ ErrorCode["CONNECTION_FAILED"] = "CONNECTION_FAILED"; /** Browser connection timed out */ ErrorCode["CONNECTION_TIMEOUT"] = "CONNECTION_TIMEOUT"; /** Browser connection was refused */ ErrorCode["CONNECTION_REFUSED"] = "CONNECTION_REFUSED"; /** Browser connection was lost during operation */ ErrorCode["CONNECTION_LOST"] = "CONNECTION_LOST"; // Browser Launch Errors /** Browser executable not found on system */ ErrorCode["BROWSER_NOT_FOUND"] = "BROWSER_NOT_FOUND"; /** Browser failed to launch */ ErrorCode["BROWSER_LAUNCH_FAILED"] = "BROWSER_LAUNCH_FAILED"; /** Browser launch operation timed out */ ErrorCode["BROWSER_LAUNCH_TIMEOUT"] = "BROWSER_LAUNCH_TIMEOUT"; /** Insufficient permissions to launch browser */ ErrorCode["BROWSER_PERMISSION_DENIED"] = "BROWSER_PERMISSION_DENIED"; // Configuration Errors /** Configuration file is invalid */ ErrorCode["CONFIG_INVALID"] = "CONFIG_INVALID"; /** Configuration file is missing */ ErrorCode["CONFIG_MISSING"] = "CONFIG_MISSING"; /** Configuration validation failed */ ErrorCode["CONFIG_VALIDATION_FAILED"] = "CONFIG_VALIDATION_FAILED"; // Tool Execution Errors /** Browser tool execution failed */ ErrorCode["TOOL_EXECUTION_FAILED"] = "TOOL_EXECUTION_FAILED"; /** Browser tool execution timed out */ ErrorCode["TOOL_TIMEOUT"] = "TOOL_TIMEOUT"; /** Invalid parameters provided to browser tool */ ErrorCode["TOOL_INVALID_PARAMS"] = "TOOL_INVALID_PARAMS"; /** Element not found on page */ ErrorCode["ELEMENT_NOT_FOUND"] = "ELEMENT_NOT_FOUND"; // Data Errors /** Failed to copy browser data */ ErrorCode["DATA_COPY_FAILED"] = "DATA_COPY_FAILED"; /** Access denied to browser data */ ErrorCode["DATA_ACCESS_DENIED"] = "DATA_ACCESS_DENIED"; /** Browser data corruption detected */ ErrorCode["DATA_CORRUPTION"] = "DATA_CORRUPTION"; // System Errors /** Insufficient system permissions */ ErrorCode["INSUFFICIENT_PERMISSIONS"] = "INSUFFICIENT_PERMISSIONS"; /** Required resource unavailable */ ErrorCode["RESOURCE_UNAVAILABLE"] = "RESOURCE_UNAVAILABLE"; /** General system error */ ErrorCode["SYSTEM_ERROR"] = "SYSTEM_ERROR"; })(ErrorCode || (ErrorCode = {})); export class MCPError extends Error { code; context; recoveryActions; userFriendly; constructor(message, code, context = {}, recoveryActions = [], userFriendly = true) { super(message); this.name = this.constructor.name; this.code = code; this.context = { ...context, timestamp: new Date() }; this.recoveryActions = recoveryActions; this.userFriendly = userFriendly; // Capture stack trace if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } } /** * Get a formatted error message with context and recovery suggestions */ getFormattedMessage() { let message = `[${this.code}] ${this.message}`; if (this.context.operation) { message += `\n Operation: ${this.context.operation}`; } if (this.context.component) { message += `\n Component: ${this.context.component}`; } if (this.context.details && Object.keys(this.context.details).length > 0) { message += `\n Details: ${JSON.stringify(this.context.details, null, 2)}`; } if (this.recoveryActions.length > 0) { message += `\n\nRecovery Actions:`; this.recoveryActions.forEach((action, index) => { message += `\n ${index + 1}. ${action.action}: ${action.description}`; if (action.command) { message += `\n Command: ${action.command}`; } }); } return message; } /** * Convert error to JSON for logging or transmission */ toJSON() { return { name: this.name, message: this.message, code: this.code, context: this.context, recoveryActions: this.recoveryActions, userFriendly: this.userFriendly, stack: this.stack }; } } /** * Browser Connection Errors */ export class BrowserConnectionError extends MCPError { constructor(message, context = {}, cause) { const recoveryActions = [ { action: 'Check Browser Status', description: 'Ensure Chrome is running with debugging enabled', command: 'chrome --remote-debugging-port=9223' }, { action: 'Verify Port', description: 'Check if the debug port is available and not blocked', command: 'curl http://localhost:9223/json/version' }, { action: 'Restart Browser', description: 'Close Chrome completely and restart with debug mode' } ]; super(message, ErrorCode.CONNECTION_FAILED, { ...context, component: 'BrowserConnection' }, recoveryActions); if (cause) { this.context.details = { ...this.context.details, cause: cause.message }; } } } /** * Browser Launch Errors */ export class BrowserLaunchError extends MCPError { constructor(message, context = {}, cause) { const recoveryActions = [ { action: 'Check Chrome Installation', description: 'Verify Chrome is installed and accessible', command: 'which chrome || which google-chrome' }, { action: 'Check Permissions', description: 'Ensure Chrome executable has proper permissions' }, { action: 'Clear Profile', description: 'Remove MCP profile directory if corrupted', command: 'rm -rf ./any-browser-mcp-profile' } ]; super(message, ErrorCode.BROWSER_LAUNCH_FAILED, { ...context, component: 'ChromeLauncher' }, recoveryActions); if (cause) { this.context.details = { ...this.context.details, cause: cause.message }; } } } /** * Configuration Errors */ export class ConfigurationError extends MCPError { constructor(message, context = {}, validationErrors) { const recoveryActions = [ { action: 'Check Config File', description: 'Verify config.json exists and is valid JSON' }, { action: 'Reset Configuration', description: 'Use default configuration if config is corrupted' }, { action: 'Validate Schema', description: 'Ensure all required configuration fields are present' } ]; super(message, ErrorCode.CONFIG_VALIDATION_FAILED, { ...context, component: 'ConfigManager', details: { validationErrors } }, recoveryActions); } } /** * Tool Execution Errors */ export class ToolExecutionError extends MCPError { constructor(toolName, message, context = {}, cause) { const recoveryActions = [ { action: 'Retry Operation', description: 'Wait a moment and try the operation again' }, { action: 'Check Browser State', description: 'Ensure browser is responsive and page is loaded' }, { action: 'Verify Parameters', description: 'Check that all tool parameters are valid' } ]; super(`Tool '${toolName}' execution failed: ${message}`, ErrorCode.TOOL_EXECUTION_FAILED, { ...context, component: 'BrowserTools', operation: toolName }, recoveryActions); if (cause) { this.context.details = { ...this.context.details, cause: cause.message }; } } } /** * Data Operation Errors */ export class DataOperationError extends MCPError { constructor(operation, message, context = {}, cause) { const recoveryActions = [ { action: 'Check Permissions', description: 'Ensure proper file system permissions for data access' }, { action: 'Verify Source Data', description: 'Check that Chrome user data directory exists and is accessible' }, { action: 'Clear Target Directory', description: 'Remove corrupted MCP profile and retry', command: 'rm -rf ./any-browser-mcp-profile' } ]; super(`Data operation '${operation}' failed: ${message}`, ErrorCode.DATA_COPY_FAILED, { ...context, component: 'ChromeLauncher', operation }, recoveryActions); if (cause) { this.context.details = { ...this.context.details, cause: cause.message }; } } } /** * Lazy Initialization Errors */ export class LazyInitializationError extends MCPError { constructor(message, context = {}, cause) { const recoveryActions = [ { action: 'Manual Browser Start', description: 'Start Chrome manually with debugging enabled', command: 'chrome --remote-debugging-port=9223' }, { action: 'Check Configuration', description: 'Verify MCP configuration allows browser launching' }, { action: 'Reset Manager State', description: 'Clear any cached connection state and retry' } ]; super(message, ErrorCode.CONNECTION_FAILED, { ...context, component: 'LazyBrowserManager' }, recoveryActions); if (cause) { this.context.details = { ...this.context.details, cause: cause.message }; } } } /** * Element Not Found Errors */ export class ElementNotFoundError extends MCPError { constructor(selector, context = {}) { const recoveryActions = [ { action: 'Wait for Element', description: 'Element might still be loading, wait a moment and retry' }, { action: 'Check Selector', description: 'Verify the CSS selector is correct and specific enough' }, { action: 'Inspect Page', description: 'Use browser dev tools to verify element exists' } ]; super(`Element not found: ${selector}`, ErrorCode.ELEMENT_NOT_FOUND, { ...context, component: 'BrowserTools', details: { selector } }, recoveryActions); } } /** * Error Factory for creating appropriate error types */ export class ErrorFactory { static createConnectionError(message, context, cause) { return new BrowserConnectionError(message, context, cause); } static createLaunchError(message, context, cause) { return new BrowserLaunchError(message, context, cause); } static createConfigError(message, context, validationErrors) { return new ConfigurationError(message, context, validationErrors); } static createToolError(toolName, message, context, cause) { return new ToolExecutionError(toolName, message, context, cause); } static createDataError(operation, message, context, cause) { return new DataOperationError(operation, message, context, cause); } static createLazyInitError(message, context, cause) { return new LazyInitializationError(message, context, cause); } static createElementNotFoundError(selector, context) { return new ElementNotFoundError(selector, context); } } //# sourceMappingURL=errors.js.map