如何配置API路由实现第三方API失败时返回本地服务器文件
实现方案
你现有代码的降级逻辑不生效,核心原因有两点:
node-fetch只有网络层面故障(断网、域名解析失败、请求超时等)才会抛出异常,第三方接口返回400、500这类HTTP错误状态时,不会进入catch块,原有err === 400的判断永远无法触发- 异常捕获范围不全,没有覆盖响应状态异常、JSON解析失败、数据处理报错等场景
可按如下逻辑调整:
- 提前加载本地兜底数据,避免每次请求重复读取文件产生额外IO
- 请求第三方接口后先校验响应状态,非2xx状态直接触发兜底
- 所有第三方接口请求、解析、处理环节的异常统一捕获,触发时返回本地数据
- 已经设置
Content-Type: application/json的前提下,直接给res.send传JS对象即可,框架会自动完成JSON序列化,不需要手动调用JSON.stringify
修正后的代码如下:
// 提前加载本地兜底JSON数据,按需替换为实际的本地文件读取逻辑 import localData from './local-fallback-data.json' assert { type: 'json' }; routes.get("/data", async (req: Request, res: Response, next: NextFunction) => { res.set({ "Cache-Control": "no-store", "Content-Type": "application/json" }); try { // 可选:添加超时控制,避免第三方接口长时间无响应阻塞请求 const controller = new AbortController(); const timer = setTimeout(() => controller.abort(), 5000); const apiResp = await fetch("https://api.blahblah.com/files", { signal: controller.signal }); clearTimeout(timer); // 校验响应状态,非2xx状态直接抛出错误走兜底 if (!apiResp.ok) { throw new Error(`API request error, status: ${apiResp.status}`); } const rawData = await apiResp.json(); const formatData = rawData.filter((item: { fork: boolean }) => item.fork === false); res.send(formatData); } catch (err) { // 第三方接口全链路异常都走兜底,返回本地数据 console.error("Third-party API request failed, return local fallback data:", err); res.send(localData); // 若有需要区分错误类型,可在此判断错误属性,非接口类错误传给全局错误中间件 // 例如:if (isSystemError(err)) next(err) } });
补充说明
- 如果本地数据需要动态更新,可以给本地数据加缓存过期逻辑,定时重新读取文件即可
- 如果需要针对特定HTTP状态码(比如400、503)做特殊处理,可在
apiResp.ok判断分支里单独处理状态码 - 若使用的node-fetch版本不支持AbortController,可替换为对应版本的超时实现方案
内容的提问来源于stack exchange,提问作者DJKI
相关产品推荐
相关产品推荐

