@equidam/mcp-server
Version:
Equidam MCP Server - Bridge between AI assistants and Equidam's company valuation API
162 lines (140 loc) • 4.51 kB
JavaScript
/**
* Error handling utilities for Equidam MCP Server
*/
/**
* Custom error classes for different types of failures
*/
class EquidamError extends Error {
constructor(message, code = 'EQUIDAM_ERROR', statusCode = 500) {
super(message);
this.name = 'EquidamError';
this.code = code;
this.statusCode = statusCode;
}
}
class AuthenticationError extends EquidamError {
constructor(message = 'Authentication failed') {
super(message, 'AUTH_ERROR', 401);
this.name = 'AuthenticationError';
}
}
class RateLimitError extends EquidamError {
constructor(message = 'Rate limit exceeded') {
super(message, 'RATE_LIMIT_ERROR', 429);
this.name = 'RateLimitError';
}
}
class ValidationError extends EquidamError {
constructor(message = 'Validation failed') {
super(message, 'VALIDATION_ERROR', 400);
this.name = 'ValidationError';
}
}
class NetworkError extends EquidamError {
constructor(message = 'Network error occurred') {
super(message, 'NETWORK_ERROR', 503);
this.name = 'NetworkError';
}
}
/**
* Convert axios error to appropriate custom error
* @param {Error} error - The axios error
* @returns {EquidamError} - Converted error
*/
function convertAxiosError(error) {
if (!error.response) {
// Network error
if (error.code === 'ECONNRESET' || error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
return new NetworkError(`Network connection failed: ${error.message}`);
}
if (error.code === 'ECONNABORTED') {
return new NetworkError('Request timeout - please try again');
}
return new NetworkError(`Network error: ${error.message}`);
}
const { status, data } = error.response;
const message = data?.message || data?.error || error.message;
switch (status) {
case 401:
return new AuthenticationError('Invalid API key or authentication failed');
case 403:
return new AuthenticationError('Access forbidden - check your API permissions');
case 429:
return new RateLimitError('Rate limit exceeded - please wait before making more requests');
case 400:
return new ValidationError(message || 'Invalid request parameters');
case 404:
return new EquidamError('API endpoint not found', 'NOT_FOUND', 404);
case 500:
case 502:
case 503:
case 504:
return new EquidamError(`Server error: ${message}`, 'SERVER_ERROR', status);
default:
return new EquidamError(`API error: ${message}`, 'API_ERROR', status);
}
}
/**
* Format error for user display
* @param {Error} error - The error to format
* @returns {string} - User-friendly error message
*/
function formatUserError(error) {
if (error instanceof AuthenticationError) {
return `Authentication Error: ${error.message}. Please check your API key.`;
}
if (error instanceof RateLimitError) {
return `Rate Limit Error: ${error.message}. Please wait a few minutes before trying again.`;
}
if (error instanceof ValidationError) {
return `Validation Error: ${error.message}. Please check your input parameters.`;
}
if (error instanceof NetworkError) {
return `Network Error: ${error.message}. Please check your internet connection.`;
}
if (error instanceof EquidamError) {
return `Equidam API Error: ${error.message}`;
}
return `Unexpected Error: ${error.message}`;
}
/**
* Determine if an error is retryable
* @param {Error} error - The error to check
* @returns {boolean} - Whether the error is retryable
*/
function isRetryableError(error) {
// Don't retry authentication or validation errors
if (error instanceof AuthenticationError || error instanceof ValidationError) {
return false;
}
// Retry network errors and server errors
if (error instanceof NetworkError) {
return true;
}
// Retry rate limit errors (with backoff)
if (error instanceof RateLimitError) {
return true;
}
// Retry 5xx server errors
if (error instanceof EquidamError && error.statusCode >= 500) {
return true;
}
// For axios errors, check specific conditions
if (error.code === 'ECONNRESET' || error.code === 'ENOTFOUND' || error.code === 'ECONNREFUSED') {
return true;
}
if (error.response?.status >= 500 || error.response?.status === 429) {
return true;
}
return false;
}
module.exports = {
EquidamError,
AuthenticationError,
RateLimitError,
ValidationError,
NetworkError,
convertAxiosError,
formatUserError,
isRetryableError
};