Deno中Fetch API随机出现无法捕获的HTTP2内部错误求助
问题分析与解决方案
是不是Deno的Bug?
是的,这个问题大概率是你使用的Deno 1.25.2版本中HTTP2/Fetch模块的实现Bug。该版本的HTTP2流错误没有被正确封装到Promise的拒绝逻辑中,导致外层try-catch无法捕获,最终触发未处理的Promise拒绝使程序崩溃。这类网络相关的异常在后续Deno版本中已被大量修复。
解决步骤
1. 升级Deno到最新稳定版
这是最优先的解决方案,新版本修复了大量HTTP2和Fetch相关的异常捕获问题。执行以下命令升级:
deno upgrade
若需指定具体稳定版本,可使用:
deno upgrade --version 1.40.0 # 替换为当前最新稳定版号
升级后重新运行程序,观察错误是否复现。
2. 强制禁用HTTP2(临时 workaround)
如果暂时无法升级,或升级后仍有问题,可强制Fetch使用HTTP/1.1避开HTTP2的Bug:
- 全局禁用HTTP2:启动Deno程序时添加
--no-http2参数:deno run --no-http2 my_script.ts - 单请求禁用HTTP2:在fetch请求配置中添加
Connection: close头:async function gFetchEvent(url: string, options: RequestInit = {}) { try { const result: Response = await fetch(url, { ...options, headers: { ...options.headers, "Connection": "close" } }); // 后续处理逻辑 } catch (err) { console.error("请求失败:", err); throw err; } }
3. 全局捕获未处理的Promise拒绝
为防止程序因漏网的未捕获异常崩溃,添加全局监听:
Deno.addListener("unhandledrejection", (event) => { event.preventDefault(); // 阻止程序默认崩溃行为 console.error("未处理的Promise拒绝:", event.reason); // 此处可添加日志记录、重试逻辑等 });
4. 完善gFetchEvent的错误捕获逻辑
确保所有异步操作都被try-catch覆盖,包括响应解析步骤(比如response.json()也可能抛出异常):
async function gFetchEvent(url: string, options: RequestInit = {}) { try { const result: Response = await fetch(url, { ...options, headers: { ...options.headers, "Connection": "close" } // 可选,强制HTTP1.1 }); if (!result.ok) { throw new Error(`HTTP错误: ${result.status} ${result.statusText}`); } const data = await result.json(); return data; } catch (err) { console.error("gFetchEvent执行失败:", err); // 可添加指数退避重试逻辑,比如重试1-2次 throw err; } }
额外建议
- 检查服务器网络环境:该问题仅出现在1blu的vServer上,可能存在网络层面的HTTP2兼容性问题(如防火墙、反向代理的HTTP2处理异常),可联系服务商确认配置。
- 增加请求重试机制:针对随机网络错误,在
gFetchEvent中添加重试逻辑,降低单次错误对程序的影响。
内容的提问来源于stack exchange,提问作者MrKleeblatt
相关产品推荐
相关产品推荐

