Vue3中使用fetch和getReader捕获GPT聊天流未捕获的TypeError
问题描述
我正在用Vue3组合式API开发聊天机器人客户端,后端采用FastAPI的POST接口返回StreamingResponse。前端使用fetch结合getReader方法处理流式响应,代码如下:
try { fetch('api...', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: jsonPrompt }) .then(response => { if (!response.ok || !response.body) { return; } const reader = response.body.getReader(); reader.read().then(function processText({ done, value }) { if (done) { console.log('Stream done'); return; } const decodedData = new TextDecoder('utf-8').decode(value); console.log('decodedData:', decodedData); //processStream(decodedData); return reader.read().then(processText); }) }) .catch(error => { console.error('Error in promise:', error); }); } catch (error) { console.error('Error:', error); }
偶尔会在流已启动但done标志返回true前出现TypeError: network error,响应状态码为200(错误信息:net::ERR_HTTP2_PROTOCOL_ERROR 200 (OK)),且外层try-catch无法捕获该错误:
请问如何在getReader处理分片数据时捕获该错误?
解决方案
要捕获流式读取过程中的网络错误,核心是处理reader.read()返回Promise的reject状态——这类错误发生在流读取阶段,而非fetch请求初始化阶段,所以外层try-catch和fetch的catch无法捕获。
方法1:给reader.read()的Promise添加catch回调
修改递归读取逻辑,为每次reader.read()的Promise追加错误捕获回调:
try { fetch('api...', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: jsonPrompt }) .then(response => { if (!response.ok || !response.body) { return; } const reader = response.body.getReader(); // 统一处理流读取错误 const handleStreamError = (error) => { console.error('流读取错误:', error); // 释放读取锁,避免资源泄漏 reader.releaseLock(); // 可添加用户提示、状态重置等逻辑 }; reader.read().then(function processText({ done, value }) { if (done) { console.log('流读取完成'); return; } const decodedData = new TextDecoder('utf-8').decode(value); console.log('解码后数据:', decodedData); //processStream(decodedData); // 递归读取时捕获错误 return reader.read().then(processText).catch(handleStreamError); }).catch(handleStreamError); // 捕获第一次读取的错误 }) .catch(error => { console.error('Fetch请求错误:', error); }); } catch (error) { console.error('全局错误:', error); }
方法2:改用async/await语法,简化错误捕获
用async函数包裹流式读取逻辑,直接用try-catch捕获所有阶段的错误,代码可读性更强:
const fetchStream = async () => { try { const response = await fetch('api...', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: jsonPrompt }); if (!response.ok || !response.body) { return; } const reader = response.body.getReader(); while (true) { try { const { done, value } = await reader.read(); if (done) { console.log('流读取完成'); break; } const decodedData = new TextDecoder('utf-8').decode(value); console.log('解码后数据:', decodedData); //processStream(decodedData); } catch (streamError) { console.error('流读取错误:', streamError); reader.releaseLock(); break; } } } catch (globalError) { console.error('请求或全局错误:', globalError); } }; // 调用流式请求函数 fetchStream();
额外提示
- 错误发生后务必调用
reader.releaseLock()释放读取锁,避免占用浏览器资源; net::ERR_HTTP2_PROTOCOL_ERROR 200多与HTTP2连接异常有关,可同步排查后端FastAPI的流式响应配置、服务器的HTTP2设置,比如是否存在响应头不规范、连接提前中断等情况。
内容的提问来源于stack exchange,提问作者matrix4use
相关产品推荐
相关产品推荐

