fu-orm-code-generator
Version:
A Model Context Protocol (MCP) server for MyBatis code generation with enterprise-grade layered architecture
204 lines (181 loc) • 4.95 kB
JavaScript
/**
* 统一错误处理系统
*/
/**
* 应用错误基类
*/
export class AppError extends Error {
/**
* @param {string} code - 错误代码
* @param {string} message - 错误消息
* @param {number} statusCode - HTTP状态码
* @param {Object} [context] - 错误上下文
*/
constructor(code, message, statusCode = 500, context = {}) {
super(message);
this.name = this.constructor.name;
this.code = code;
this.statusCode = statusCode;
this.context = context;
this.timestamp = new Date().toISOString();
// 保持堆栈跟踪
if (Error.captureStackTrace) {
Error.captureStackTrace(this, this.constructor);
}
}
/**
* 序列化错误信息
*/
toJSON() {
return {
name: this.name,
code: this.code,
message: this.message,
statusCode: this.statusCode,
context: this.context,
timestamp: this.timestamp,
stack: this.stack
};
}
}
/**
* 业务逻辑错误
*/
export class BusinessError extends AppError {
constructor(code, message, context = {}) {
super(code, message, 400, context);
}
}
/**
* 验证错误
*/
export class ValidationError extends AppError {
constructor(message, context = {}) {
super(ErrorCodes.VALIDATION_ERROR, message, 422, context);
}
}
/**
* 资源未找到错误
*/
export class NotFoundError extends AppError {
constructor(resource, identifier, context = {}) {
const message = `${resource} with identifier "${identifier}" not found`;
super(ErrorCodes.RESOURCE_NOT_FOUND, message, 404, { resource, identifier, ...context });
}
}
/**
* 网络错误
*/
export class NetworkError extends AppError {
constructor(message, context = {}) {
super(ErrorCodes.NETWORK_ERROR, message, 503, context);
}
}
/**
* 文件系统错误
*/
export class FileSystemError extends AppError {
constructor(operation, path, originalError, context = {}) {
const message = `File system operation "${operation}" failed for path "${path}": ${originalError.message}`;
super(ErrorCodes.FILESYSTEM_ERROR, message, 500, {
operation,
path,
originalError: originalError.message,
...context
});
}
}
/**
* 安全错误
*/
export class SecurityError extends AppError {
constructor(message, context = {}) {
super(ErrorCodes.SECURITY_ERROR, message, 403, context);
}
}
/**
* 错误代码枚举
*/
export const ErrorCodes = {
// 通用错误
VALIDATION_ERROR: 'VALIDATION_ERROR',
RESOURCE_NOT_FOUND: 'RESOURCE_NOT_FOUND',
NETWORK_ERROR: 'NETWORK_ERROR',
FILESYSTEM_ERROR: 'FILESYSTEM_ERROR',
SECURITY_ERROR: 'SECURITY_ERROR',
// 模板相关错误
TEMPLATE_NOT_FOUND: 'TEMPLATE_NOT_FOUND',
TEMPLATE_ALREADY_EXISTS: 'TEMPLATE_ALREADY_EXISTS',
TEMPLATE_DOWNLOAD_FAILED: 'TEMPLATE_DOWNLOAD_FAILED',
TEMPLATE_EXTRACT_FAILED: 'TEMPLATE_EXTRACT_FAILED',
// 配置相关错误
CONFIG_READ_ERROR: 'CONFIG_READ_ERROR',
CONFIG_WRITE_ERROR: 'CONFIG_WRITE_ERROR',
CONFIG_INVALID_FORMAT: 'CONFIG_INVALID_FORMAT',
// HTTP相关错误
HTTP_REQUEST_FAILED: 'HTTP_REQUEST_FAILED',
HTTP_TIMEOUT: 'HTTP_TIMEOUT',
HTTP_RATE_LIMITED: 'HTTP_RATE_LIMITED'
};
/**
* 错误处理工具函数
*/
export class ErrorHandler {
/**
* 将错误转换为用户友好的消息
* @param {Error} error - 错误对象
* @returns {string} 用户友好的错误消息
*/
static toUserMessage(error) {
if (error instanceof ValidationError) {
return `输入验证失败: ${error.message}`;
}
if (error instanceof NotFoundError) {
return `资源未找到: ${error.message}`;
}
if (error instanceof NetworkError) {
return `网络请求失败: ${error.message}`;
}
if (error instanceof FileSystemError) {
return `文件操作失败: ${error.message}`;
}
if (error instanceof BusinessError) {
return error.message;
}
// 对于未知错误,返回通用消息
return '操作失败,请稍后重试';
}
/**
* 记录错误日志
* @param {Error} error - 错误对象
* @param {Object} [context] - 额外上下文
*/
static log(error, context = {}) {
const logData = {
timestamp: new Date().toISOString(),
error: error instanceof AppError ? error.toJSON() : {
name: error.name,
message: error.message,
stack: error.stack
},
context
};
// MCP 服务器禁用控制台输出,避免干扰 STDIO 通信
// 错误信息仅通过文件日志记录
}
/**
* 创建标准化的工具返回结果
* @param {Error} error - 错误对象
* @returns {import('../types').ToolResult} 标准化的工具结果
*/
static toToolResult(error) {
const userMessage = this.toUserMessage(error);
this.log(error);
return {
content: [{
type: 'text',
text: userMessage
}]
};
}
}