Chrome MCP Server错误处理最佳实践:异常捕获与恢复机制
在Chrome MCP Server(Model Context Protocol Server)开发中,错误处理直接影响扩展稳定性和用户体验。本文从异常捕获、错误恢复、类型分类三个维度,结合app/native-server/src/server/index.ts和app/chrome-extension/entrypoints/background/semantic-similarity.ts等核心模块代码,系统梳理错误处理最佳实践。
异常捕获策略
多层级try-catch架构
MCP Server采用"边界捕获+层级处理"模式,在网络请求、模型初始化等高风险模块设置捕获边界。
// 网络请求异常捕获 [app/native-server/src/server/index.ts]
async function handleRequest(request, reply) {
try {
const transport = getTransport(sessionId);
if (!transport) {
reply.code(400).send({ error: "无效会话" });
return;
}
await transport.handleRequest(request.raw, reply.raw, request.body);
} catch (error) {
if (!reply.sent) {
reply.code(500).send({
error: "请求处理失败",
details: process.env.NODE_ENV === "development" ? error.message : undefined
});
}
}
}
异步操作错误处理
针对Chrome扩展特有的异步API(如tabs.captureVisibleTab),采用"try-catch+超时控制"双重保障:
// 截图操作异常捕获 [app/chrome-extension/entrypoints/background/tools/browser/screenshot.ts]
async function captureVisibleArea(tabId) {
try {
// 添加超时控制的异步捕获
const capturePromise = chrome.tabs.captureVisibleTab({ format: 'png' });
const dataUrl = await Promise.race([
capturePromise,
new Promise((_, reject) =>
setTimeout(() => reject(new Error("截图超时")), 10000)
)
]);
if (!dataUrl) throw new Error("截图数据为空");
return dataUrl;
} catch (error) {
// 分类错误类型并记录
const errorType = error.message.includes("超时") ? "timeout" : "capture_failed";
logError(`[${errorType}] ${error.message}`, { tabId });
throw new Error(`截图失败: ${error.message}`);
}
}
错误恢复机制
状态重置恢复
语义相似度引擎初始化失败时,通过状态清理实现可重试机制:
// 模型引擎重置恢复 [app/chrome-extension/entrypoints/background/semantic-similarity.ts]
async function initializeSemanticEngine() {
try {
await updateModelStatus('initializing', 0);
const response = await chrome.runtime.sendMessage({
target: 'offscreen',
type: 'SIMILARITY_ENGINE_INIT',
config: currentModelConfig
});
if (!response.success) throw new Error(response.error);
await updateModelStatus('ready', 100);
} catch (error) {
console.error('引擎初始化失败:', error);
// 关键状态重置
await updateModelStatus('error', 0, error.message);
currentBackgroundModelConfig = null;
// 触发轻量级恢复流程
if (error.message.includes('模型文件')) {
return cleanupCorruptedModels().then(() => ({ retry: true }));
}
return { retry: false };
}
}
操作回滚策略
全页面截图等多步骤操作失败时,执行页面状态回滚:
// 操作回滚机制 [app/chrome-extension/entrypoints/background/tools/browser/screenshot.ts]
async function captureFullPage(tabId, initialScroll) {
let originalState;
try {
// 保存原始状态
originalState = await savePageState(tabId);
// 修改页面状态(隐藏滚动条、固定定位元素)
await preparePageForCapture(tabId);
// 执行多段截图
return await stitchMultipleCaptures(tabId);
} catch (error) {
console.error('全页截图失败:', error);
throw error;
} finally {
// 无论成功失败均恢复状态
if (originalState) {
await restorePageState(tabId, originalState);
}
}
}
错误类型分类与处理
预定义错误类型体系
系统定义三级错误分类标准,在app/common/constants.ts中维护错误码字典:
// 错误类型常量定义 [app/common/constants.ts]
export const ERROR_TYPES = {
NETWORK: {
FETCH_FAILED: "network.fetch_failed",
TIMEOUT: "network.timeout",
CORS: "network.cors"
},
STORAGE: {
QUOTA_EXCEEDED: "storage.quota_exceeded",
CORRUPTED: "storage.corrupted"
},
MODEL: {
DOWNLOAD_FAILED: "model.download_failed",
INVALID_FORMAT: "model.invalid_format",
DIMENSION_MISMATCH: "model.dimension_mismatch"
}
};
// 错误处理路由表
export const ERROR_HANDLERS = {
"model.download_failed": handleModelDownloadError,
"network.timeout": handleNetworkTimeout,
"storage.quota_exceeded": handleStorageQuotaExceeded
};
错误分析工具函数
通过错误消息模式识别,实现自动化错误分类:
// 错误类型分析 [app/chrome-extension/entrypoints/background/semantic-similarity.ts]
function analyzeErrorType(errorMessage) {
const message = errorMessage.toLowerCase();
if (message.includes('network') || message.includes('fetch')) return 'network';
if (message.includes('corrupt') || message.includes('invalid') || message.includes('onnx')) return 'file';
if (message.includes('dimension')) return 'model.dimension_mismatch';
return 'unknown';
}
错误日志与监控
结构化日志实现
// 错误日志工具 [app/native-server/src/util/logger.ts]
export function logError(message, context = {}) {
const logEntry = {
timestamp: new Date().toISOString(),
level: "error",
message,
context: {
pid: process.pid,
module: context.module || "unknown",
...context
},
stack: context.error?.stack || new Error().stack
};
// 开发环境直接输出
if (process.env.NODE_ENV === "development") {
console.error(`[${logEntry.timestamp}] ${logEntry.message}`, logEntry.context);
} else {
// 生产环境结构化存储
fs.appendFileSync(ERROR_LOG_PATH, JSON.stringify(logEntry) + "\n");
// 严重错误触发监控告警
if (context.severity === "critical") {
triggerAlert(logEntry);
}
}
}
错误监控指标
关键错误指标跟踪实现:
// 错误指标收集 [app/native-server/src/util/metrics.ts]
export const ErrorMetrics = {
counters: new Map(),
incrementError(type) {
const key = `error.${type}`;
this.counters.set(key, (this.counters.get(key) || 0) + 1);
// 阈值告警:连续5次相同错误触发警告
if (this.counters.get(key) >= 5) {
logWarning(`错误阈值触发: ${key}`, { count: this.counters.get(key) });
}
},
resetCounters() {
this.counters.clear();
}
};
// 使用示例
ErrorMetrics.incrementError("model.initialize_failed");
实战案例:全流程错误处理
以语义向量搜索功能为例,展示完整错误处理链路:
// 向量搜索错误处理全流程
async function vectorSearch(query, tabId) {
try {
// 1. 参数验证
if (!query || query.length < 2) {
throw new Error("查询词长度不足");
}
// 2. 前置状态检查
const engineStatus = await getModelStatus();
if (engineStatus !== "ready") {
throw new Error(`引擎未就绪: 当前状态${engineStatus}`);
}
// 3. 核心逻辑执行
const results = await executeVectorSearch(query);
return results;
} catch (error) {
// 4. 错误分类处理
const errorType = analyzeErrorType(error.message);
// 5. 恢复策略执行
if (errorType === "model.not_ready") {
await initializeSemanticEngine();
throw new Error("引擎已自动重启,请重试操作");
}
// 6. 错误包装与传递
throw new Error(`[${errorType}] ${error.message}`);
} finally {
// 7. 资源清理
cleanupSearchResources();
}
}
总结与最佳实践清单
核心原则
- 防御性编程:所有外部输入、API调用必须包裹错误处理
- 错误分类:建立错误类型体系,区分可恢复/不可恢复错误
- 状态隔离:错误发生后确保状态一致性,避免级联失败
- 开发/生产环境差异化:生产环境隐藏敏感信息,开发环境提供调试详情
检查清单
- 所有异步操作是否包含超时控制?
- 错误信息是否包含唯一错误码?
- 敏感操作是否实现事务式回滚?
- 错误日志是否包含足够上下文?
- 关键错误是否有监控告警机制?
完整错误处理规范可参考docs/TROUBLESHOOTING.md,包含常见错误码速查和恢复方案。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



