Skip to main content
Glama

Feishu MCP Server

error.ts6.7 kB
import { Logger } from './logger.js'; /** * 飞书API错误接口 */ export interface FeishuApiError { code?: number; msg?: string; error?: { field_violations?: Array<{ field: string; description?: string; value?: any; }>; troubleshooter?: string; }; } /** * 错误排查指南映射 */ const errorGuides: Record<string, string> = { // 飞书API标准错误码 '1770002': '资源未找到。请检查文档ID/块ID是否正确,并确保您有权限访问该资源。', '1770001': '权限不足。请确保应用有足够的权限访问此资源。', '1770003': '内部服务错误。请稍后重试。', '1770004': '参数格式错误。请检查API请求参数是否正确。', '1770005': '请求频率限制。请减少请求频率后重试。', '1770006': '操作冲突。可能有其他用户正在编辑同一资源。', '1770007': '资源已被删除。请检查资源是否存在。', '1770008': '资源已被归档。请检查资源状态。', '1770015': '文档或文件夹已被移动。请使用新的位置访问。', // 身份验证和通用错误 '99991671': '飞书应用身份验证失败。请检查App ID和App Secret是否正确,或者重新注册飞书应用。', '99991663': '权限不足。请确保:\n1. 应用已获得正确的权限范围\n2. 文档已与应用共享\n3. 您有访问该文档的权限', '99991672': '请求频率超过限制。请稍后再试或优化代码减少请求次数。', '99991661': '资源不存在。请检查文档ID/块ID是否正确,并确保资源仍然存在。', '99991648': '文档ID格式不正确。请检查ID格式,应为标准飞书文档ID、URL或Token。', 'token_invalid': '访问令牌无效。请尝试刷新访问令牌。', 'invalid_token': '访问令牌无效。请尝试刷新访问令牌。', '404': '资源未找到。请检查URL或ID是否正确。', '403': '访问被拒绝。请检查权限设置并确保您有足够的访问权限。', '401': '未授权。请检查认证凭据或尝试重新获取访问令牌。', '400': '请求参数有误。请检查提供的参数格式和值是否正确。', '500': '服务器内部错误。请稍后重试或联系飞书支持团队。' }; /** * 格式化错误消息 * 对飞书API各种错误响应格式进行统一处理 * * @param error 原始错误 * @param context 错误上下文(可选) * @returns 格式化的错误消息 */ export function formatErrorMessage(error: any, context?: string): string { try { // 预处理错误对象 if (!error) { return '发生未知错误'; } // 确定错误类型 let errorCode: number | string | undefined; let errorMsg = ''; let fieldViolations: any[] = []; let troubleshooter = ''; let logId = ''; // 处理飞书API标准错误格式 if (error.apiError) { const apiError = error.apiError; errorCode = apiError.code; errorMsg = apiError.msg || ''; if (apiError.error) { fieldViolations = apiError.error.field_violations || []; troubleshooter = apiError.error.troubleshooter || ''; logId = apiError.error.log_id || ''; } } // 处理直接包含code和msg的格式 else if (error.code !== undefined && error.msg !== undefined) { errorCode = error.code; errorMsg = error.msg; if (error.error) { fieldViolations = error.error.field_violations || []; troubleshooter = error.error.troubleshooter || ''; logId = error.error.log_id || ''; } } // 处理HTTP类错误 else if (error.status) { errorCode = error.status; errorMsg = error.statusText || error.err || '请求失败'; } // 处理标准Error对象 else if (error instanceof Error) { errorMsg = error.message; } // 处理字符串错误 else if (typeof error === 'string') { errorMsg = error; } // 处理其他对象类型的错误 else if (typeof error === 'object') { errorMsg = error.message || error.error || JSON.stringify(error); } // 构建基本错误消息 let formattedMessage = ''; if (context) { formattedMessage += `${context}: `; } if (errorCode !== undefined) { formattedMessage += `${errorMsg} (错误码: ${errorCode})`; } else { formattedMessage += errorMsg; } // 添加日志ID if (logId) { formattedMessage += `\n日志ID: ${logId}`; } // 添加字段验证错误信息 if (fieldViolations && fieldViolations.length > 0) { formattedMessage += '\n字段验证错误:'; fieldViolations.forEach((violation) => { let detail = `\n - ${violation.field}`; if (violation.description) { detail += `: ${violation.description}`; } if (violation.value !== undefined) { detail += `,提供的值: ${violation.value}`; } formattedMessage += detail; }); } // 添加排查建议 if (troubleshooter) { formattedMessage += `\n\n排查建议:\n${troubleshooter}`; } else { // 尝试添加预定义的错误指南 const errorCodeStr = String(errorCode); if (errorGuides[errorCodeStr]) { formattedMessage += `\n\n排查建议:\n${errorGuides[errorCodeStr]}`; } else { // 如果没有精确匹配,尝试通过错误消息内容模糊匹配 for (const [key, guide] of Object.entries(errorGuides)) { if (errorMsg.toLowerCase().includes(key.toLowerCase())) { formattedMessage += `\n\n排查建议:\n${guide}`; break; } } } } return formattedMessage; } catch (e) { Logger.error("格式化错误消息时发生错误:", e); return typeof error === 'string' ? error : '发生未知错误'; } } /** * 包装错误为标准格式 * * @param message 错误消息前缀 * @param originalError 原始错误 * @returns 包装后的错误对象 */ export function wrapError(message: string, originalError: any): Error { const errorMessage = formatErrorMessage(originalError); return new Error(`${message}: ${errorMessage}`); } /** * 授权异常类 * 用于处理需要用户授权的情况 */ export class AuthRequiredError extends Error { public readonly authType: 'tenant' | 'user'; public readonly authUrl?: string; public readonly message: string; constructor(authType: 'tenant' | 'user', message: string, authUrl?: string) { super(message); this.name = 'AuthRequiredError'; this.authType = authType; this.authUrl = authUrl; this.message = message; } }

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/cso1z/Feishu-MCP'

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