vibe-coder-mcp
Version:
Production-ready MCP server with complete agent integration, multi-transport support, and comprehensive development automation tools for AI-assisted workflows.
360 lines (359 loc) • 12.5 kB
JavaScript
import { AppError } from '../../../utils/errors.js';
import logger from '../../../logger.js';
export class EnhancedError extends AppError {
category;
severity;
context;
recoveryActions;
retryable;
userFriendly;
constructor(message, category, severity, context, options = {}) {
super(message, { cause: options.cause });
this.category = category;
this.severity = severity;
this.context = context;
this.recoveryActions = options.recoveryActions || [];
this.retryable = options.retryable ?? false;
this.userFriendly = options.userFriendly ?? false;
this.logError();
}
getUserFriendlyMessage() {
if (this.userFriendly) {
return this.message;
}
switch (this.category) {
case 'configuration':
return 'There is a configuration issue that needs to be resolved.';
case 'validation':
return 'The provided input is invalid or incomplete.';
case 'network':
return 'A network connection issue occurred.';
case 'timeout':
return 'The operation took too long to complete.';
case 'resource':
return 'System resources are insufficient or unavailable.';
case 'permission':
return 'Permission denied for the requested operation.';
case 'dependency':
return 'A required dependency is missing or unavailable.';
case 'agent':
return 'An agent encountered an issue while processing the task.';
case 'task':
return 'The task could not be completed as requested.';
default:
return 'An unexpected error occurred.';
}
}
getRecoverySuggestions() {
return this.recoveryActions
.sort((a, b) => a.priority - b.priority)
.map(action => `${action.action}: ${action.description}`);
}
logError() {
const logData = {
category: this.category,
severity: this.severity,
context: this.context,
retryable: this.retryable,
recoveryActions: this.recoveryActions.length,
stack: this.stack
};
switch (this.severity) {
case 'critical':
logger.fatal(logData, this.message);
break;
case 'high':
logger.error(logData, this.message);
break;
case 'medium':
logger.warn(logData, this.message);
break;
case 'low':
logger.info(logData, this.message);
break;
}
}
}
export class ConfigurationError extends EnhancedError {
constructor(message, context, options = {}) {
const recoveryActions = [
{
action: 'Check Configuration',
description: 'Verify configuration values are correct and properly formatted',
automated: false,
priority: 2
},
{
action: 'Validate Environment Variables',
description: 'Ensure all required environment variables are set',
automated: true,
priority: 3
}
];
if (options.configKey) {
recoveryActions.unshift({
action: `Update ${options.configKey}`,
description: `Set ${options.configKey} to a valid value${options.expectedValue ? ` (expected: ${options.expectedValue})` : ''}`,
automated: false,
priority: 1
});
}
super(message, 'configuration', 'high', context, {
cause: options.cause,
recoveryActions,
retryable: true,
userFriendly: options.userFriendly ?? true
});
}
}
export class TaskExecutionError extends EnhancedError {
constructor(message, context, options = {}) {
const recoveryActions = [
{
action: 'Retry Task',
description: 'Attempt to execute the task again',
automated: true,
priority: 1
},
{
action: 'Reassign Agent',
description: 'Assign the task to a different agent',
automated: true,
priority: 2
}
];
if (options.taskType) {
recoveryActions.push({
action: 'Check Task Requirements',
description: `Verify that the ${options.taskType} task requirements are met`,
automated: false,
priority: 3
});
}
super(message, 'task', 'medium', context, {
cause: options.cause,
recoveryActions,
retryable: options.retryable ?? true,
userFriendly: options.userFriendly ?? true
});
}
}
export class AgentError extends EnhancedError {
constructor(message, context, options = {}) {
const recoveryActions = [
{
action: 'Restart Agent',
description: 'Restart the agent to resolve temporary issues',
automated: true,
priority: 1
},
{
action: 'Check Agent Health',
description: 'Verify agent is responding and functioning correctly',
automated: true,
priority: 2
}
];
if (options.agentType) {
recoveryActions.push({
action: `Verify ${options.agentType} Agent`,
description: `Check that the ${options.agentType} agent is properly configured`,
automated: false,
priority: 3
});
}
super(message, 'agent', 'medium', context, {
cause: options.cause,
recoveryActions,
retryable: true,
userFriendly: options.userFriendly ?? true
});
}
}
export class TimeoutError extends EnhancedError {
constructor(message, context, options = {}) {
const recoveryActions = [
{
action: 'Increase Timeout',
description: 'Configure a longer timeout for this operation',
automated: false,
priority: 1
},
{
action: 'Retry Operation',
description: 'Attempt the operation again',
automated: true,
priority: 2
}
];
if (options.operation) {
recoveryActions.push({
action: `Optimize ${options.operation}`,
description: `Review and optimize the ${options.operation} operation for better performance`,
automated: false,
priority: 3
});
}
super(message, 'timeout', 'medium', context, {
cause: options.cause,
recoveryActions,
retryable: true,
userFriendly: options.userFriendly ?? true
});
}
}
export class ResourceError extends EnhancedError {
constructor(message, context, options = {}) {
const recoveryActions = [
{
action: 'Free Resources',
description: 'Release unused resources to make more available',
automated: true,
priority: 1
},
{
action: 'Wait for Resources',
description: 'Wait for resources to become available',
automated: true,
priority: 2
}
];
if (options.resourceType) {
recoveryActions.push({
action: `Increase ${options.resourceType}`,
description: `Allocate more ${options.resourceType} resources`,
automated: false,
priority: 3
});
}
super(message, 'resource', 'high', context, {
cause: options.cause,
recoveryActions,
retryable: true,
userFriendly: options.userFriendly ?? true
});
}
}
export class ValidationError extends EnhancedError {
constructor(message, context, options = {}) {
const recoveryActions = [
{
action: 'Correct Input',
description: 'Provide valid input according to the expected format',
automated: false,
priority: 1
}
];
if (options.field && options.expectedFormat) {
recoveryActions.push({
action: `Fix ${options.field}`,
description: `Ensure ${options.field} follows the format: ${options.expectedFormat}`,
automated: false,
priority: 1
});
}
super(message, 'validation', 'medium', context, {
cause: options.cause,
recoveryActions,
retryable: false,
userFriendly: options.userFriendly ?? true
});
}
}
export class NetworkError extends EnhancedError {
constructor(message, context, options = {}) {
const recoveryActions = [
{
action: 'Check Network Connection',
description: 'Verify network connectivity and DNS resolution',
automated: true,
priority: 1
},
{
action: 'Retry Request',
description: 'Attempt the network request again',
automated: true,
priority: 2
}
];
if (options.endpoint) {
recoveryActions.push({
action: `Verify ${options.endpoint}`,
description: `Check that ${options.endpoint} is accessible and responding`,
automated: true,
priority: 2
});
}
super(message, 'network', 'medium', context, {
cause: options.cause,
recoveryActions,
retryable: true,
userFriendly: options.userFriendly ?? true
});
}
}
export class ErrorFactory {
static createError(type, message, context, options = {}) {
const factoryOptions = { ...options, userFriendly: false };
switch (type) {
case 'configuration':
return new ConfigurationError(message, context, factoryOptions);
case 'task':
return new TaskExecutionError(message, context, factoryOptions);
case 'agent':
return new AgentError(message, context, factoryOptions);
case 'timeout':
return new TimeoutError(message, context, factoryOptions);
case 'resource':
return new ResourceError(message, context, factoryOptions);
case 'validation':
return new ValidationError(message, context, factoryOptions);
case 'network':
return new NetworkError(message, context, factoryOptions);
default:
return new EnhancedError(message, type, 'medium', context, factoryOptions);
}
}
}
export class ErrorContextBuilder {
context = {
timestamp: new Date()
};
component(component) {
this.context.component = component;
return this;
}
operation(operation) {
this.context.operation = operation;
return this;
}
taskId(taskId) {
this.context.taskId = taskId;
return this;
}
agentId(agentId) {
this.context.agentId = agentId;
return this;
}
projectId(projectId) {
this.context.projectId = projectId;
return this;
}
sessionId(sessionId) {
this.context.sessionId = sessionId;
return this;
}
metadata(metadata) {
this.context.metadata = { ...this.context.metadata, ...metadata };
return this;
}
build() {
if (!this.context.component || !this.context.operation) {
throw new Error('Component and operation are required for error context');
}
return this.context;
}
}
export function createErrorContext(component, operation) {
return new ErrorContextBuilder().component(component).operation(operation);
}