Node.js后端如何用try/catch实现请求最多10次重试失败返回null
Node.js 重试请求函数修正方案
原有代码的核心问题
- 无空值防护:直接访问
icfDocuments.nodes[0].revision.pdfUrl时,若返回结构中nodes数组为空、revision字段不存在,会直接抛出异常,虽然会进入重试逻辑,但存在非预期报错风险 - 无有效pdfUrl时未触发等待:当请求本身成功但返回结果无有效pdfUrl时,代码不会进入catch块,不会等待15秒就直接发起下一次请求,不符合重试间隔要求
- 等待逻辑仅覆盖请求异常场景:只有请求报错时才会执行15秒等待,正常返回但结果不符合要求的场景无间隔直接重试
修正后完整代码
// 等待工具函数 const sleep = (ms) => { return new Promise((resolve) => { setTimeout(resolve, ms); }); }; async function getData(documentId, log) { const MAX_RETRIES = 10; const RETRY_DELAY = 15000; // 循环次数:首次+10次重试 = 共11次尝试,符合最多重试10次的要求 for (let i = 0; i <= MAX_RETRIES; i += 1) { let hasValidPdfUrl = false; let requestError = null; let icfDocuments = null; try { const response = await request( CONSENT_SERVICE_URL, getICFDocumentRecipientsQuery, { documentId } ); icfDocuments = response.icfDocuments; // 可选链做空值防护,判断是否存在非空pdfUrl hasValidPdfUrl = !!icfDocuments?.nodes?.[0]?.revision?.pdfUrl; if (hasValidPdfUrl) { return icfDocuments; } } catch (err) { requestError = err; } // 不是最后一次尝试的话,先等待再重试 if (i < MAX_RETRIES) { log.debug('等待后重试获取pdfUrl,等待时长:', RETRY_DELAY, 'ms'); if (requestError) { log.debug('本次请求失败原因:', requestError.message, '当前重试次数:', i + 1); } else { log.debug('本次返回无有效pdfUrl,当前重试次数:', i + 1); } await sleep(RETRY_DELAY); } } // 10次重试全部失败,返回null符合需求 return null; }
修正说明
- 空值防护:使用可选链
?.校验返回结构的每一层字段,避免结构不符合预期时的异常报错 - 统一重试逻辑:不管是请求异常、还是返回结果无有效pdfUrl,都会走相同的等待重试逻辑,符合15秒间隔要求
- 次数逻辑正确:循环执行11次(首次请求+10次重试),所有尝试都失败后返回null,完全匹配需求
内容的提问来源于stack exchange,提问作者Jakub
相关产品推荐
相关产品推荐

