Skip to main content
Glama
errorHandler.js2.67 kB
/** * Error handler utility for YNAB MCP * Provides consistent error handling and messaging */ const { logger } = require('./logger'); // Custom error classes class YnabMcpError extends Error { constructor(message, statusCode = 500, code = 'INTERNAL_ERROR') { super(message); this.name = this.constructor.name; this.statusCode = statusCode; this.code = code; Error.captureStackTrace(this, this.constructor); } } class AuthenticationError extends YnabMcpError { constructor(message = 'Authentication failed', code = 'AUTH_ERROR') { super(message, 401, code); } } class TokenError extends YnabMcpError { constructor(message = 'Token error', code = 'TOKEN_ERROR') { super(message, 401, code); } } class RateLimitError extends YnabMcpError { constructor(message = 'Rate limit exceeded', code = 'RATE_LIMIT_ERROR') { super(message, 429, code); } } class ValidationError extends YnabMcpError { constructor(message = 'Validation failed', code = 'VALIDATION_ERROR') { super(message, 400, code); } } class NotFoundError extends YnabMcpError { constructor(message = 'Resource not found', code = 'NOT_FOUND_ERROR') { super(message, 404, code); } } // Error handler function for API responses const handleError = (error, req, res, next) => { // Log the error if (error instanceof YnabMcpError) { logger.warn(`${error.name}: ${error.message}`); } else { logger.error('Unhandled error:', error); } // Determine the status code and format error for response const statusCode = error.statusCode || 500; const errorResponse = { error: { message: error.message || 'Internal server error', code: error.code || 'INTERNAL_ERROR', status: statusCode } }; // Only include stack trace in development if (process.env.NODE_ENV === 'development' && error.stack) { errorResponse.error.stack = error.stack; } // Send the error response res.status(statusCode).json(errorResponse); }; // Format error for MCP response const formatMcpError = (error) => { const baseError = { error: { message: error.message || 'Internal server error', code: error.code || 'INTERNAL_ERROR' } }; // Add additional context based on error type if (error instanceof AuthenticationError) { baseError.error.authenticationRequired = true; } else if (error instanceof RateLimitError) { baseError.error.retryAfter = error.retryAfter || 3600; // Default to 1 hour } return baseError; }; module.exports = { YnabMcpError, AuthenticationError, TokenError, RateLimitError, ValidationError, NotFoundError, handleError, formatMcpError };

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/mattweg/ynab-mcp'

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