Skip to main content
Glama
YUChoe

SQLite MCP Server

by YUChoe
ErrorHandler.ts7.95 kB
/** * 통합 오류 처리 시스템 * MCP 서버의 모든 오류를 일관되게 처리하고 분류 */ /** * 데이터베이스 오류 타입 */ export enum DatabaseErrorType { INVALID_PATH = 'INVALID_PATH', PERMISSION_DENIED = 'PERMISSION_DENIED', DISK_FULL = 'DISK_FULL', CORRUPTED_DATABASE = 'CORRUPTED_DATABASE', CONNECTION_FAILED = 'CONNECTION_FAILED' } /** * SQL 오류 타입 */ export enum SQLErrorType { SYNTAX_ERROR = 'SYNTAX_ERROR', TABLE_NOT_EXISTS = 'TABLE_NOT_EXISTS', COLUMN_NOT_EXISTS = 'COLUMN_NOT_EXISTS', CONSTRAINT_VIOLATION = 'CONSTRAINT_VIOLATION', TYPE_MISMATCH = 'TYPE_MISMATCH' } /** * MCP 프로토콜 오류 타입 */ export enum MCPErrorType { INVALID_REQUEST = 'INVALID_REQUEST', TOOL_NOT_FOUND = 'TOOL_NOT_FOUND', INVALID_PARAMETERS = 'INVALID_PARAMETERS', INTERNAL_ERROR = 'INTERNAL_ERROR' } /** * 데이터베이스 오류 인터페이스 */ export interface DatabaseError { type: DatabaseErrorType; message: string; path: string; originalError?: Error; } /** * SQL 오류 인터페이스 */ export interface SQLError { type: SQLErrorType; message: string; query: string; position?: number; } /** * MCP 프로토콜 오류 인터페이스 */ export interface MCPError { type: MCPErrorType; message: string; code: number; data?: any; } /** * 통합 오류 처리 클래스 */ export class ErrorHandler { /** * 데이터베이스 오류 분류 및 처리 */ static handleDatabaseError(error: Error, path: string): DatabaseError { const message = error.message.toLowerCase(); if (message.includes('no such file') || message.includes('cannot open')) { return { type: DatabaseErrorType.INVALID_PATH, message: `데이터베이스 파일을 찾을 수 없습니다: ${path}`, path, originalError: error }; } if (message.includes('permission denied') || message.includes('access denied')) { return { type: DatabaseErrorType.PERMISSION_DENIED, message: `데이터베이스 파일에 대한 접근 권한이 없습니다: ${path}`, path, originalError: error }; } if (message.includes('disk full') || message.includes('no space')) { return { type: DatabaseErrorType.DISK_FULL, message: `디스크 공간이 부족합니다: ${path}`, path, originalError: error }; } if (message.includes('corrupt') || message.includes('malformed')) { return { type: DatabaseErrorType.CORRUPTED_DATABASE, message: `데이터베이스 파일이 손상되었습니다: ${path}`, path, originalError: error }; } return { type: DatabaseErrorType.CONNECTION_FAILED, message: `데이터베이스 연결에 실패했습니다: ${error.message}`, path, originalError: error }; } /** * SQL 오류 분류 및 처리 */ static handleSQLError(error: Error, query: string): SQLError { const message = error.message.toLowerCase(); if (message.includes('syntax error') || message.includes('near')) { return { type: SQLErrorType.SYNTAX_ERROR, message: `SQL 구문 오류: ${error.message}`, query }; } if (message.includes('no such table')) { return { type: SQLErrorType.TABLE_NOT_EXISTS, message: `테이블이 존재하지 않습니다: ${error.message}`, query }; } if (message.includes('no such column')) { return { type: SQLErrorType.COLUMN_NOT_EXISTS, message: `컬럼이 존재하지 않습니다: ${error.message}`, query }; } if (message.includes('constraint') || message.includes('unique') || message.includes('foreign key')) { return { type: SQLErrorType.CONSTRAINT_VIOLATION, message: `제약 조건 위반: ${error.message}`, query }; } if (message.includes('type') || message.includes('affinity')) { return { type: SQLErrorType.TYPE_MISMATCH, message: `데이터 타입 불일치: ${error.message}`, query }; } return { type: SQLErrorType.SYNTAX_ERROR, message: `SQL 실행 오류: ${error.message}`, query }; } /** * MCP 프로토콜 오류 분류 및 처리 */ static handleMCPError(error: Error, context?: any): MCPError { const message = error.message.toLowerCase(); if (message.includes('tool not found') || message.includes('unknown tool')) { return { type: MCPErrorType.TOOL_NOT_FOUND, message: `도구를 찾을 수 없습니다: ${error.message}`, code: -32601, data: context }; } if (message.includes('invalid parameters') || message.includes('validation')) { return { type: MCPErrorType.INVALID_PARAMETERS, message: `잘못된 매개변수: ${error.message}`, code: -32602, data: context }; } if (message.includes('invalid request') || message.includes('malformed')) { return { type: MCPErrorType.INVALID_REQUEST, message: `잘못된 요청: ${error.message}`, code: -32600, data: context }; } return { type: MCPErrorType.INTERNAL_ERROR, message: `내부 서버 오류: ${error.message}`, code: -32603, data: context }; } /** * 오류를 MCP 응답 형식으로 변환 */ static formatErrorResponse(error: DatabaseError | SQLError | MCPError): any { return { content: [ { type: 'text' as const, text: JSON.stringify({ success: false, error: error.message, errorType: error.type, ...(('code' in error) && { code: error.code }), ...(('path' in error) && { path: error.path }), ...(('query' in error) && { query: error.query }) }, null, 2) } ], isError: true }; } /** * 일반 오류를 처리하고 적절한 형식으로 변환 */ static handleGenericError(error: unknown, context?: { path?: string; query?: string; tool?: string }): any { if (!(error instanceof Error)) { return this.formatErrorResponse({ type: MCPErrorType.INTERNAL_ERROR, message: `알 수 없는 오류: ${String(error)}`, code: -32603 }); } // 컨텍스트에 따라 적절한 오류 처리기 선택 if (context?.path && (error.message.includes('database') || error.message.includes('sqlite'))) { const dbError = this.handleDatabaseError(error, context.path); return this.formatErrorResponse(dbError); } if (context?.query) { const sqlError = this.handleSQLError(error, context.query); return this.formatErrorResponse(sqlError); } if (context?.tool) { const mcpError = this.handleMCPError(error, context); return this.formatErrorResponse(mcpError); } // 기본 MCP 오류로 처리 const mcpError = this.handleMCPError(error); return this.formatErrorResponse(mcpError); } /** * 오류 로깅 */ static logError(error: DatabaseError | SQLError | MCPError, context?: any): void { const timestamp = new Date().toISOString(); const logEntry = { timestamp, errorType: error.type, message: error.message, context, ...(('originalError' in error) && error.originalError && { stack: error.originalError.stack }) }; console.error('SQLite MCP Server Error:', JSON.stringify(logEntry, null, 2)); } }

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/YUChoe/sqlite-mcp'

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