Skip to main content
Glama
error-handler.ts3.93 kB
/** * Centralized error handling utility for MCP tools */ // Import the McpToolResponse type from response-formatter to ensure consistency import type { McpToolResponse } from "./response-formatter.js"; /** * Standard error response interface */ export interface ErrorResponse { message: string; code?: string; details?: unknown; } /** * Specific error types for better categorization */ export enum ErrorType { API_ERROR = "API_ERROR", VALIDATION_ERROR = "VALIDATION_ERROR", NOT_FOUND = "NOT_FOUND", NETWORK_ERROR = "NETWORK_ERROR", UNKNOWN_ERROR = "UNKNOWN_ERROR", } /** * Enhanced error response with type categorization */ export interface EnhancedErrorResponse extends ErrorResponse { type: ErrorType; } /** * Create a standardized error response for MCP tools * * @param error - The error object or message * @param context - Optional context information about where the error occurred * @returns A formatted MCP tool response with error information */ export function createErrorResponse( error: unknown, context?: string, ): McpToolResponse { const errorMessage = error instanceof Error ? error.message : String(error); // Extract error code if available (for logging purposes) const errorCode = error instanceof Error && "code" in error ? (error as { code?: string }).code : undefined; // Determine error type based on error characteristics const errorType = determineErrorType(error, errorMessage); // Include error code in logs if available if (errorCode) { console.debug(`Error code: ${errorCode}`); } const contextPrefix = context ? `[${context}] ` : ""; const formattedMessage = `${contextPrefix}Error: ${errorMessage}`; // Log the error for server-side debugging with type information console.error(`${formattedMessage} (Type: ${errorType})`, error); return { content: [ { type: "text" as const, text: formattedMessage, }, ], isError: true, }; } /** * Determine the type of error based on error characteristics */ function determineErrorType(error: unknown, message: string): ErrorType { const messageLower = message.toLowerCase(); const nameLower = error instanceof Error ? error.name.toLowerCase() : ""; if ( nameLower.includes("network") || messageLower.includes("network") || nameLower.includes("fetch") || messageLower.includes("fetch") || nameLower.includes("timeout") || messageLower.includes("timeout") ) { return ErrorType.NETWORK_ERROR; } if ( nameLower.includes("validation") || messageLower.includes("validation") || messageLower.includes("invalid") || messageLower.includes("required") ) { return ErrorType.VALIDATION_ERROR; } if ( messageLower.includes("not found") || messageLower.includes("404") || messageLower.includes("does not exist") ) { return ErrorType.NOT_FOUND; } if ( nameLower.includes("api") || messageLower.includes("api") || messageLower.includes("server error") || messageLower.includes("500") ) { return ErrorType.API_ERROR; } return ErrorType.UNKNOWN_ERROR; } /** * Wrap an async function with standardized error handling * * This function preserves the parameter types of the wrapped function while * providing error handling. The returned function accepts Record<string, unknown> * (as required by MCP SDK) but internally casts to the original parameter type. * * @param fn - The async function to wrap * @param context - Context information for error messages * @returns A function that catches errors and returns standardized error responses */ export function withErrorHandling<TParams extends Record<string, unknown>>( fn: (args: TParams) => Promise<McpToolResponse>, context: string, ): (args: Record<string, unknown>) => Promise<McpToolResponse> { return async (args: Record<string, unknown>) => { try { return await fn(args as TParams); } catch (error) { return createErrorResponse(error, context); } }; }

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/chrisdoc/hevy-mcp'

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