Skip to main content
Glama
mcp-errors.ts5.27 kB
/** * MCP Error Classes - Structured error handling for MCP protocol * * THE IMPLEMENTOR'S RULE: No fallbacks, no wrapping - expose real problems * MCP SDK will automatically convert these to JSON-RPC 2.0 format */ import { MCPErrorCodes, MCPErrorCode } from './error-codes'; /** * Base MCP Error class * All MCP errors should extend this class */ export abstract class MCPError extends Error { public readonly code: MCPErrorCode; public readonly data?: unknown; constructor(message: string, code: MCPErrorCode, data?: unknown) { super(message); this.code = code; this.data = data; this.name = this.constructor.name; } /** * Convert to JSON-RPC 2.0 error format */ toJsonRpc(): { code: number; message: string; data?: unknown } { return { code: this.code, message: this.message, ...(this.data !== undefined && { data: this.data }), }; } } /** * Validation Error - Invalid input parameters * Maps to JSON-RPC error code -32602 (Invalid params) */ export class MCPValidationError extends MCPError { constructor( message: string, code: MCPErrorCode = MCPErrorCodes.VALIDATION_FAILED, data?: unknown ) { super(message, code, data); } } /** * Database Error - Database operations failed * Maps to JSON-RPC error code -32603 (Internal error) */ export class MCPDatabaseError extends MCPError { constructor( message: string, code: MCPErrorCode = MCPErrorCodes.DATABASE_OPERATION_FAILED, data?: unknown ) { super(message, code, data); } } /** * Service Error - External service issues * Maps to JSON-RPC error code -32603 (Internal error) */ export class MCPServiceError extends MCPError { constructor( message: string, code: MCPErrorCode = MCPErrorCodes.SERVICE_UNAVAILABLE, data?: unknown ) { super(message, code, data); } } /** * Resource Not Found Error * Maps to JSON-RPC error code -32602 (Invalid params) */ export class MCPResourceNotFoundError extends MCPError { constructor( resourceType: string, resourceId: string, code: MCPErrorCode = MCPErrorCodes.MEMORY_NOT_FOUND ) { super(`${resourceType} not found: ${resourceId}`, code, { resourceType, resourceId, }); } } /** * Operation Error - Operation-specific failures * Maps to JSON-RPC error code -32603 (Internal error) */ export class MCPOperationError extends MCPError { constructor( message: string, code: MCPErrorCode = MCPErrorCodes.OPERATION_TIMEOUT, data?: unknown ) { super(message, code, data); } } /** * Helper function to detect Neo4j-specific errors */ export function detectNeo4jError(error: unknown): MCPError | null { if (!(error instanceof Error)) return null; const message = error.message; // Constraint violations if (message.includes('ConstraintValidationFailed')) { const idMatch = message.match(/Node\(\d+\) already exists with label `\w+` and property `id` = '([^']+)'/); const id = idMatch ? idMatch[1] : 'unknown'; return new MCPDatabaseError( `Duplicate ID constraint violation: ${id}`, MCPErrorCodes.DUPLICATE_ID, { duplicateId: id } ); } // Service unavailable if (message.includes('ServiceUnavailable') || message.includes('Connection refused')) { return new MCPDatabaseError( 'Database service unavailable', MCPErrorCodes.DATABASE_UNAVAILABLE, { originalError: message } ); } // Database not found if (message.includes('Database does not exist')) { const dbMatch = message.match(/Database '([^']+)' does not exist/); const dbName = dbMatch ? dbMatch[1] : 'unknown'; return new MCPDatabaseError( `Database not found: ${dbName}`, MCPErrorCodes.DATABASE_NOT_FOUND, { database: dbName } ); } // Unknown function (missing plugins) if (message.includes('Unknown function')) { const funcMatch = message.match(/Unknown function '([^']+)'/); const funcName = funcMatch ? funcMatch[1] : 'unknown'; if (funcName.includes('gds.')) { return new MCPServiceError( 'Neo4j Graph Data Science (GDS) plugin is required but not installed', MCPErrorCodes.GDS_PLUGIN_MISSING, { function: funcName, installUrl: 'https://dozerdb.org/', verifyCommand: 'RETURN gds.similarity.cosine([1,2,3], [2,3,4])' } ); } } return null; } /** * Type guard to check if error is an MCP error */ export function isMCPError(error: unknown): error is MCPError { return error instanceof MCPError; } /** * Convert any error to MCP error * Used as last resort when specific error type cannot be determined */ export function toMCPError(error: unknown): MCPError { if (error instanceof MCPError) { return error; } // Try to detect Neo4j-specific errors const neo4jError = detectNeo4jError(error); if (neo4jError) { return neo4jError; } // Generic error handling if (error instanceof Error) { return new MCPOperationError( error.message, MCPErrorCodes.INTERNAL_ERROR, { originalError: error.name } ); } return new MCPOperationError( String(error), MCPErrorCodes.INTERNAL_ERROR, { originalError: error } ); }

Latest Blog Posts

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/sylweriusz/mcp-neo4j-memory-server'

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