Skip to main content
Glama
error.ts4.48 kB
/** * Error handling utilities */ import { LoggerFactory } from "./logger.js"; import { config } from "@/config/Config.js"; const logger = LoggerFactory.server().child({ component: "ErrorUtils" }); // Environment flag to control legacy console logging noise. Default enabled to preserve // backward compatibility and existing test expectations. Set LEGACY_ERROR_LOGS=0 to disable // the direct console.error side-channel (structured logger still emits). const LEGACY_ERROR_LOGS_ENABLED = config().error.legacyLogsEnabled; // Internal helper to avoid sprinkling conditionals function legacyConsoleError(...args: unknown[]) { if (LEGACY_ERROR_LOGS_ENABLED) { console.error(...args); } } // Test hook: exported only for instrumentation in unit tests (tree-shakeable) // @__PURE__ This constant has no side effects and can be dropped in production builds export const __errorUtilsLogger = logger; export function getErrorMessage(error: unknown): string { if (error instanceof Error) { return error.message; } if (typeof error === "string") { return error; } if (error && typeof error === "object" && "message" in error) { return String(error.message); } return "Unknown error occurred"; } export function isError(error: unknown): error is Error { return error instanceof Error; } export function logAndReturn<T>(error: unknown, defaultValue: T): T { const message = getErrorMessage(error); // Legacy console logging (can be disabled via LEGACY_ERROR_LOGS=0) legacyConsoleError("Error occurred:", message); logger.warn("Error occurred - returning default value", { error: message, }); return defaultValue; } /** * Enhanced error handler for consistent tool error handling */ export function handleToolError(error: unknown, operation: string, context?: Record<string, unknown>): never { const message = getErrorMessage(error); const errObj = error instanceof Error ? error : new Error(message); // Legacy console logging (can be disabled via LEGACY_ERROR_LOGS=0) legacyConsoleError(`Error in ${operation}:`, errObj); if (context) { legacyConsoleError("Context:", context); } logger.error(`Error in ${operation}`, { error: message, ...(context && { context }), }); if (error instanceof Error && error.stack) { logger.debug("Error stack trace", { stack: error.stack }); } // Provide more specific error messages based on error content if (message.includes("ECONNREFUSED") || message.includes("ENOTFOUND")) { throw new Error( `Connection failed during ${operation}. Please check your WordPress site URL and network connection.`, ); } if (message.includes("401") || message.includes("Unauthorized")) { throw new Error(`Authentication failed during ${operation}. Please check your WordPress credentials.`); } if (message.includes("403") || message.includes("Forbidden")) { throw new Error(`Permission denied during ${operation}. Please check your user permissions.`); } if (message.includes("429") || message.includes("Too Many Requests")) { throw new Error(`Rate limit exceeded during ${operation}. Please try again later.`); } throw new Error(`Failed to ${operation}: ${message}`); } /** * Validates required parameters */ export function validateRequired(params: Record<string, unknown> | unknown, required: string[]): void { // Runtime guard: ensure params is a non-null object (tests expect throw on invalid input) if (params === null || typeof params !== "object") { throw new Error("Parameters must be an object"); } // Only treat undefined or null as missing; accept legitimate falsy values: 0, false, "" const obj = params as Record<string, unknown>; const missing = required.filter((key) => obj[key] === undefined || obj[key] === null); if (missing.length > 0) { throw new Error(`Missing required parameters: ${missing.join(", ")}`); } } /** * Validates site parameter for multi-site configurations */ export function validateSite(site: string | undefined, availableSites: string[]): string { if (!site) { if (availableSites.length === 1) { return availableSites[0]; } throw new Error( `Site parameter is required when multiple sites are configured. Available sites: ${availableSites.join(", ")}`, ); } if (!availableSites.includes(site)) { throw new Error(`Site '${site}' not found. Available sites: ${availableSites.join(", ")}`); } return site; }

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/docdyhr/mcp-wordpress'

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