Skip to main content
Glama
errors.ts8.24 kB
/** * Custom error classes for the Cursor Chat History MCP server */ /** * Base error class for all MCP-related errors */ export class MCPError extends Error { public readonly code: string; public readonly statusCode: number; constructor(message: string, code: string = 'MCP_ERROR', statusCode: number = 500) { super(message); this.name = this.constructor.name; this.code = code; this.statusCode = statusCode; // Maintains proper stack trace for where our error was thrown (only available on V8) if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } } } /** * Error thrown when database operations fail */ export class DatabaseError extends MCPError { constructor(message: string, originalError?: Error) { super( originalError ? `Database error: ${message}. Original: ${originalError.message}` : `Database error: ${message}`, 'DATABASE_ERROR', 500 ); if (originalError && originalError.stack) { this.stack = `${this.stack}\nCaused by: ${originalError.stack}`; } } } /** * Error thrown when database connection fails */ export class DatabaseConnectionError extends DatabaseError { constructor(dbPath: string, originalError?: Error) { super( `Failed to connect to database at path: ${dbPath}`, originalError ); // Override the code property by redefining it Object.defineProperty(this, 'code', { value: 'DATABASE_CONNECTION_ERROR', writable: false, enumerable: true, configurable: false }); } } /** * Error thrown when a conversation is not found */ export class ConversationNotFoundError extends MCPError { public readonly conversationId: string; constructor(conversationId: string) { super(`Conversation not found: ${conversationId}`, 'CONVERSATION_NOT_FOUND', 404); this.conversationId = conversationId; } } /** * Error thrown when a bubble message is not found */ export class BubbleMessageNotFoundError extends MCPError { public readonly composerId: string; public readonly bubbleId: string; constructor(composerId: string, bubbleId: string) { super( `Bubble message not found: ${bubbleId} in conversation ${composerId}`, 'BUBBLE_MESSAGE_NOT_FOUND', 404 ); this.composerId = composerId; this.bubbleId = bubbleId; } } /** * Error thrown when input validation fails */ export class ValidationError extends MCPError { public readonly field?: string; public readonly value?: any; constructor(message: string, field?: string, value?: any) { super(`Validation error: ${message}`, 'VALIDATION_ERROR', 400); this.field = field; this.value = value; } } /** * Error thrown when required parameters are missing */ export class MissingParameterError extends ValidationError { constructor(parameterName: string) { super(`Missing required parameter: ${parameterName}`, parameterName); Object.defineProperty(this, 'code', { value: 'MISSING_PARAMETER', writable: false, enumerable: true, configurable: false }); } } /** * Error thrown when parameter values are invalid */ export class InvalidParameterError extends ValidationError { constructor(parameterName: string, value: any, expectedType?: string) { const message = expectedType ? `Invalid parameter '${parameterName}': expected ${expectedType}, got ${typeof value}` : `Invalid parameter '${parameterName}': ${value}`; super(message, parameterName, value); Object.defineProperty(this, 'code', { value: 'INVALID_PARAMETER', writable: false, enumerable: true, configurable: false }); } } /** * Error thrown when file system operations fail */ export class FileSystemError extends MCPError { public readonly path: string; constructor(message: string, path: string, originalError?: Error) { super( originalError ? `File system error: ${message}. Original: ${originalError.message}` : `File system error: ${message}`, 'FILESYSTEM_ERROR', 500 ); this.path = path; if (originalError && originalError.stack) { this.stack = `${this.stack}\nCaused by: ${originalError.stack}`; } } } /** * Error thrown when database path cannot be detected */ export class DatabasePathNotFoundError extends FileSystemError { constructor(attemptedPaths: string[]) { super( `Could not find Cursor database. Attempted paths: ${attemptedPaths.join(', ')}`, attemptedPaths[0] || 'unknown' ); Object.defineProperty(this, 'code', { value: 'DATABASE_PATH_NOT_FOUND', writable: false, enumerable: true, configurable: false }); } } /** * Error thrown when parsing chat data fails */ export class ConversationParseError extends MCPError { public readonly conversationId?: string; constructor(message: string, conversationId?: string, originalError?: Error) { super( originalError ? `Parse error: ${message}. Original: ${originalError.message}` : `Parse error: ${message}`, 'CONVERSATION_PARSE_ERROR', 500 ); this.conversationId = conversationId; if (originalError && originalError.stack) { this.stack = `${this.stack}\nCaused by: ${originalError.stack}`; } } } /** * Error thrown when search operations fail */ export class SearchError extends MCPError { public readonly query: string; constructor(message: string, query: string, originalError?: Error) { super( originalError ? `Search error: ${message}. Original: ${originalError.message}` : `Search error: ${message}`, 'SEARCH_ERROR', 500 ); this.query = query; if (originalError && originalError.stack) { this.stack = `${this.stack}\nCaused by: ${originalError.stack}`; } } } /** * Error thrown when cache operations fail */ export class CacheError extends MCPError { public readonly operation: string; public readonly key?: string; constructor(message: string, operation: string, key?: string, originalError?: Error) { super( originalError ? `Cache error: ${message}. Original: ${originalError.message}` : `Cache error: ${message}`, 'CACHE_ERROR', 500 ); this.operation = operation; this.key = key; if (originalError && originalError.stack) { this.stack = `${this.stack}\nCaused by: ${originalError.stack}`; } } } /** * Utility function to check if an error is an instance of MCPError */ export function isMCPError(error: any): error is MCPError { return error instanceof MCPError; } /** * Utility function to extract error information for logging */ export function getErrorInfo(error: any): { message: string; code: string; statusCode: number; stack?: string; originalError?: string; } { // Handle null and undefined if (error === null || error === undefined) { return { message: 'Unknown error occurred', code: 'UNKNOWN_ERROR', statusCode: 500, }; } if (isMCPError(error)) { const result: any = { message: error.message, code: error.code, statusCode: error.statusCode, stack: error.stack, }; // Extract original error info for nested errors if (error instanceof DatabaseError || error instanceof FileSystemError || error instanceof ConversationParseError || error instanceof SearchError || error instanceof CacheError) { // Check if the error message contains "Original: " which indicates a nested error const originalMatch = error.message.match(/Original: (.+)$/); if (originalMatch) { result.originalError = originalMatch[1]; } } return result; } if (error instanceof Error) { return { message: error.message, code: 'UNKNOWN_ERROR', statusCode: 500, stack: error.stack, }; } // Handle objects with toString method if (error && typeof error === 'object' && typeof error.toString === 'function') { return { message: error.toString(), code: 'UNKNOWN_ERROR', statusCode: 500, }; } return { message: String(error), code: 'UNKNOWN_ERROR', statusCode: 500, }; }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vltansky/cursor-conversations-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server