deepsource-mcp-server
Version:
Model Context Protocol server for DeepSource
195 lines • 7.26 kB
JavaScript
/**
* @fileoverview MCP-compliant error handling utilities
*
* This module provides standardized error handling for Model Context Protocol (MCP)
* servers, including error types, formatting, and response generation that comply
* with MCP specifications.
*/
/**
* Standard MCP error codes based on JSON-RPC 2.0 specification
* These codes are exported for use by consumers of the library
*/
export var MCPErrorCode;
(function (MCPErrorCode) {
// JSON-RPC 2.0 standard error codes
MCPErrorCode[MCPErrorCode["PARSE_ERROR"] = -32700] = "PARSE_ERROR";
MCPErrorCode[MCPErrorCode["INVALID_REQUEST"] = -32600] = "INVALID_REQUEST";
MCPErrorCode[MCPErrorCode["METHOD_NOT_FOUND"] = -32601] = "METHOD_NOT_FOUND";
MCPErrorCode[MCPErrorCode["INVALID_PARAMS"] = -32602] = "INVALID_PARAMS";
MCPErrorCode[MCPErrorCode["INTERNAL_ERROR"] = -32603] = "INTERNAL_ERROR";
// MCP-specific error codes (range -32000 to -32099)
MCPErrorCode[MCPErrorCode["SERVER_ERROR"] = -32000] = "SERVER_ERROR";
MCPErrorCode[MCPErrorCode["RESOURCE_NOT_FOUND"] = -32001] = "RESOURCE_NOT_FOUND";
MCPErrorCode[MCPErrorCode["AUTHENTICATION_ERROR"] = -32002] = "AUTHENTICATION_ERROR";
MCPErrorCode[MCPErrorCode["AUTHORIZATION_ERROR"] = -32003] = "AUTHORIZATION_ERROR";
MCPErrorCode[MCPErrorCode["RATE_LIMITED"] = -32004] = "RATE_LIMITED";
MCPErrorCode[MCPErrorCode["TIMEOUT_ERROR"] = -32005] = "TIMEOUT_ERROR";
MCPErrorCode[MCPErrorCode["VALIDATION_ERROR"] = -32006] = "VALIDATION_ERROR";
MCPErrorCode[MCPErrorCode["DEPENDENCY_ERROR"] = -32007] = "DEPENDENCY_ERROR";
MCPErrorCode[MCPErrorCode["CONFIGURATION_ERROR"] = -32008] = "CONFIGURATION_ERROR";
// Additional error codes for compatibility
MCPErrorCode[MCPErrorCode["NETWORK_ERROR"] = -32009] = "NETWORK_ERROR";
MCPErrorCode[MCPErrorCode["CLIENT_ERROR"] = -32010] = "CLIENT_ERROR";
})(MCPErrorCode || (MCPErrorCode = {}));
/**
* MCP error categories for better error classification
* These categories are exported for use by consumers of the library
*/
export var MCPErrorCategory;
(function (MCPErrorCategory) {
MCPErrorCategory["CLIENT_ERROR"] = "client_error";
MCPErrorCategory["SERVER_ERROR"] = "server_error";
MCPErrorCategory["NETWORK_ERROR"] = "network_error";
MCPErrorCategory["VALIDATION_ERROR"] = "validation_error";
MCPErrorCategory["AUTHENTICATION_ERROR"] = "authentication_error";
MCPErrorCategory["RESOURCE_ERROR"] = "resource_error";
MCPErrorCategory["INTERNAL_ERROR"] = "internal_error";
MCPErrorCategory["TRANSPORT_ERROR"] = "transport_error";
})(MCPErrorCategory || (MCPErrorCategory = {}));
/**
* Enhanced error class for MCP-compliant errors
*/
export class MCPError extends Error {
name = 'MCPError';
code;
category;
details;
cause;
retryable;
userFriendly;
timestamp;
constructor(info) {
super(info.message);
this.code = info.code;
this.category = info.category;
if (info.details !== undefined) {
this.details = info.details;
}
if (info.cause !== undefined) {
this.cause = info.cause;
}
this.retryable = info.retryable ?? false;
this.userFriendly = info.userFriendly ?? true;
this.timestamp = new Date();
// Maintain proper stack trace
if (Error.captureStackTrace) {
Error.captureStackTrace(this, MCPError);
}
}
/**
* Converts the error to a JSON-serializable object
*/
toJSON() {
return {
name: this.name,
message: this.message,
code: this.code,
category: this.category,
details: this.details,
retryable: this.retryable,
userFriendly: this.userFriendly,
timestamp: this.timestamp.toISOString(),
stack: this.stack,
};
}
}
// Re-export factory functions
export { MCPErrorFactory } from './mcp-error-factory.js';
// Re-export converter functions
export { MCPErrorConverter } from './mcp-error-converter.js';
// Re-export formatter functions
export { MCPErrorFormatter } from './mcp-error-formatter.js';
/**
* Type guard to check if an error is an MCPError
*/
export function isMCPError(error) {
return error instanceof MCPError;
}
/**
* Validates that a value is not null or undefined
*/
export function validateRequired(value, fieldName) {
if (value === null || value === undefined) {
throw new MCPError({
code: MCPErrorCode.VALIDATION_ERROR,
category: MCPErrorCategory.VALIDATION_ERROR,
message: `Validation failed: ${fieldName} is required`,
retryable: false,
userFriendly: true,
});
}
return value;
}
/**
* Validates that a string is not empty
*/
export function validateNonEmptyString(value, fieldName) {
const validated = validateRequired(value, fieldName);
if (typeof validated !== 'string') {
throw new MCPError({
code: MCPErrorCode.VALIDATION_ERROR,
category: MCPErrorCategory.VALIDATION_ERROR,
message: `Validation failed: ${fieldName} must be a non-empty string`,
retryable: false,
userFriendly: true,
});
}
if (!validated.trim()) {
throw new MCPError({
code: MCPErrorCode.VALIDATION_ERROR,
category: MCPErrorCategory.VALIDATION_ERROR,
message: `Validation failed: ${fieldName} must be a non-empty string`,
retryable: false,
userFriendly: true,
});
}
return validated.trim();
}
/**
* Validates that a number is within a specified range
*/
export function validateNumberRange(value, fieldName, min, max) {
if (typeof value !== 'number' || isNaN(value)) {
throw new MCPError({
code: MCPErrorCode.VALIDATION_ERROR,
category: MCPErrorCategory.VALIDATION_ERROR,
message: `Validation failed: ${fieldName} must be a valid number`,
retryable: false,
userFriendly: true,
});
}
if (min !== undefined && value < min) {
throw new MCPError({
code: MCPErrorCode.VALIDATION_ERROR,
category: MCPErrorCategory.VALIDATION_ERROR,
message: `Validation failed: ${fieldName} must be >= ${min}`,
retryable: false,
userFriendly: true,
});
}
if (max !== undefined && value > max) {
throw new MCPError({
code: MCPErrorCode.VALIDATION_ERROR,
category: MCPErrorCategory.VALIDATION_ERROR,
message: `Validation failed: ${fieldName} must be <= ${max}`,
retryable: false,
userFriendly: true,
});
}
return value;
}
/**
* Higher-order function to wrap handlers with MCP-compliant error handling
*/
export function withMCPErrorHandling(handler, context) {
return async (params) => {
try {
return await handler(params);
}
catch (error) {
const { createErrorResponse } = await import('./mcp-error-formatter.js');
return createErrorResponse(error, context);
}
};
}
//# sourceMappingURL=mcp-errors.js.map