refactor(http-factory): fix defaultIsRefreshFailure, add test coverage, update docs - #21
Conversation
…for deduplication and runtime headers
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
|
Warning Review limit reached
Next review available in: 22 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
Walkthrough本次改动重写了 apps/web/src/services/api/http-factory 模块:引入统一的 normalizeError/invokeOnError 错误处理、TokenRefreshManager 冷却与并发去重、DedupeManager 请求合并、可配置重试策略、headersProvider 动态请求头及 onBusinessResponse 钩子,重构类型体系并同步更新测试、文档与示例配置,另有小幅无关调整(.gitignore、CLAUDE.md 符号链接、cache-capabilities 错误状态提取)。 ChangesHTTP 客户端核心重构
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
apps/web/src/services/api/http-factory/index.ts (1)
155-178: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
retryAfterRefresh这里会重复调用onError。
refreshAccessToken()的失败分支已经走过一次invokeOnError({ type: "refresh" });这里的catch又会再包一层。instance.request(config)的重试失败也会先在响应拦截器里触发一次invokeOnError,随后再次进入这里被重复处理。这样onError可能被触发两次以上,并且错误会被二次转换。这里应直接抛出标准化后的错误,不要再次调用invokeOnError。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/index.ts` around lines 155 - 178, `retryAfterRefresh` 里的 catch 会重复触发 `onError` 并二次包装错误,因为 `refreshAccessToken()` 和 `instance.request(config)` 的失败已经在其他拦截器路径里调用过 `invokeOnError`。请在该分支中保留 `normalizeError(error)` 的标准化结果,但直接抛出它,不要再次调用 `invokeOnError`;重点检查 `retryAfterRefresh`、`refreshAccessToken` 和 `instance.request` 这条重试链路,避免重复上报和重复转换。
🧹 Nitpick comments (11)
apps/web/src/services/api/http-factory/types/token.ts (1)
4-7: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win接口命名未遵循
I前缀规范。
AccessTokenDetail是接口(interface),按仓库规范应命名为IAccessTokenDetail。As per coding guidelines: "Use PascalCase for type and interface names, with
Iprefix for interfaces (e.g.,IUser)".🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/types/token.ts` around lines 4 - 7, The interface name does not follow the repository’s `I` prefix convention. Update the `AccessTokenDetail` interface in `token.ts` to use the required interface naming style, and make sure any references to `AccessTokenDetail` elsewhere are renamed to match the new `IAccessTokenDetail` symbol.Source: Coding guidelines
apps/web/src/services/api/http-factory/types/http-client-options.ts (1)
13-29: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win多个接口未遵循
I前缀命名规范。
DedupePolicy、RetryPolicy、HttpClientOptions均为接口,按仓库规范应命名为IDedupePolicy、IRetryPolicy、IHttpClientOptions。As per coding guidelines: "Use PascalCase for type and interface names, with
Iprefix for interfaces (e.g.,IUser)".Also applies to: 42-57, 65-68
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/types/http-client-options.ts` around lines 13 - 29, Rename the interface types to follow the repository’s `I`-prefixed PascalCase convention: change `DedupePolicy`, `RetryPolicy`, and `HttpClientOptions` to `IDedupePolicy`, `IRetryPolicy`, and `IHttpClientOptions` in the `http-client-options` types module. Update any related references in the same file and nearby type usages so the exported API and all consumers continue to compile with the new names.Source: Coding guidelines
apps/web/src/services/api/http-factory/types/common.ts (1)
6-11: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win多个接口未遵循
I前缀命名规范。
RequestRetryState、ErrorContext、ErrorMessages均为接口,按仓库规范应分别命名为IRequestRetryState、IErrorContext、IErrorMessages。As per coding guidelines: "Use PascalCase for type and interface names, with
Iprefix for interfaces (e.g.,IUser)".Also applies to: 24-29, 34-37
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/types/common.ts` around lines 6 - 11, Rename the interface types in common.ts to match the repository’s `I`-prefix convention: change `RequestRetryState`, `ErrorContext`, and `ErrorMessages` to `IRequestRetryState`, `IErrorContext`, and `IErrorMessages`. Update any references to these symbols across the related HTTP factory types and usages so the renamed interfaces remain consistent and compile cleanly.Source: Coding guidelines
apps/web/src/services/api/http-factory/__tests__/http-client.refresh.test.ts (2)
5-15: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value无效的
axiosmock,未改变任何行为。该 mock 只是原样重建
axios模块的isAxiosError,没有实际替换逻辑,属于冗余代码,可以直接移除,测试会使用真实的axios.isAxiosError达到相同效果。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/__tests__/http-client.refresh.test.ts` around lines 5 - 15, The axios mock in the http-client.refresh test is redundant because it only re-exposes the real isAxiosError behavior without changing anything. Remove the vi.mock("axios", ...) block from the test setup so the suite uses the actual axios implementation directly, and keep the rest of the test file unchanged.
17-31: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
makeAxiosError辅助函数与http-client.retry-policy.test.ts中的实现重复。两个文件的
makeAxiosError逻辑几乎相同(仅多了code字段),建议提取到共享测试工具文件中以减少重复维护成本。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/__tests__/http-client.refresh.test.ts` around lines 17 - 31, The test helper makeAxiosError is duplicated between this suite and http-client.retry-policy.test.ts, so the error construction logic should be shared instead of maintained in two places. Move the common AxiosError factory into a reusable test utility and update http-client.refresh.test.ts to import it, keeping only the extra code field handling here if needed. Use the existing makeAxiosError symbol in both tests as the reference point when extracting the shared helper.apps/web/src/services/api/http-factory/__tests__/http-client.retry-policy.test.ts (2)
21-35: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
makeAxiosError与http-client.refresh.test.ts中的实现重复。建议提取共享测试工具函数,减少重复维护成本。
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/__tests__/http-client.retry-policy.test.ts` around lines 21 - 35, The makeAxiosError helper in http-client.retry-policy.test.ts duplicates the same AxiosError setup used in http-client.refresh.test.ts, so extract this shared test utility into a common test helper and reuse it from both specs. Move the reusable helper into a shared location near the existing http-client test helpers, then update the retry-policy and refresh tests to import and call that shared function instead of maintaining separate copies.
9-19: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value无效的
axiosmock,未改变任何行为。与
http-client.refresh.test.ts中相同,该 mock 只是原样重建axios模块,未实际改变行为,可以移除。🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/__tests__/http-client.retry-policy.test.ts` around lines 9 - 19, The axios mock in the http-client retry policy test is redundant because it simply recreates the real module without changing behavior. Remove the vi.mock("axios", ...) setup from the retry-policy test file and keep the test using the actual axios export behavior, matching the approach used in http-client.refresh.test.ts.apps/web/src/services/api/http-factory/__tests__/http-client.token.test.ts (1)
42-116: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value多处使用
as any绕过类型检查。按编码规范应避免
any类型。这里可以改用更精确的类型断言(例如as unknown as AccessTokenResult)或直接构造符合联合类型的非法分支值,减少any的滥用。鉴于这是测试文件且影响有限,优先级不高。As per coding guidelines, "Forbid
anytype; prioritize using existing project type definitions" for**/*.{ts,tsx}.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/__tests__/http-client.token.test.ts` around lines 42 - 116, 测试用例里多处通过 as any 绕过了类型检查,违反了禁止 any 的规范。请在 http-client.token.test.ts 中的 normalizeTokenResult 相关断言里,改用更精确的类型断言或直接构造符合项目类型定义的输入,优先复用 AccessTokenResult 等已有类型,避免 any 出现在测试代码中。Source: Coding guidelines
apps/web/src/services/api/http-factory/__tests__/http-client.test.ts (3)
856-868: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value避免使用
any类型。866 行
config: {} as any违反项目对 TypeScript 文件禁止any类型的规范,建议改为对整个 mock 响应对象做类型断言,而非在字段上使用any。♻️ 建议修复
- onBusinessResponse: () => ({ - status: 200, - data: { replaced: true }, - statusText: "OK", - headers: {}, - config: {} as any, - }), + onBusinessResponse: () => + ({ + status: 200, + data: { replaced: true }, + statusText: "OK", + headers: {}, + config: {}, + }) as AxiosResponse,As per coding guidelines, "Forbid
anytype; prioritize using existing project type definitions" (**/*.{ts,tsx}).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/__tests__/http-client.test.ts` around lines 856 - 868, The test mock in onBusinessResponse uses a field-level any cast on config, which violates the no-any rule. Update the http-client.test.ts fixture in the onBusinessResponse case by typing the whole mocked AxiosResponse object with the existing AxiosResponse type (or an equivalent project type) instead of using config: {} as any, so the createHttpClient test remains type-safe without any.Source: Coding guidelines
608-646: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win建议为 fake timers 增加 try/finally 保护。
若 640-643 行的断言失败,
vi.useRealTimers()(645 行)不会被执行,fake timer 状态会泄漏到后续用例,导致连锁性、难以定位的测试失败。♻️ 建议修复
- const responsePromise = http.get("/profile"); - await vi.advanceTimersByTimeAsync(2000); - const response = await responsePromise; - - expect(response.data).toEqual({ ok: true }); - - vi.useRealTimers(); + try { + const responsePromise = http.get("/profile"); + await vi.advanceTimersByTimeAsync(2000); + const response = await responsePromise; + + expect(response.data).toEqual({ ok: true }); + } finally { + vi.useRealTimers(); + }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/__tests__/http-client.test.ts` around lines 608 - 646, Test case in http-client.test.ts uses vi.useFakeTimers() without guaranteed cleanup, so a failure before the end leaves fake timers enabled for later tests. Wrap the body of the retry test around the createHttpClient, queueMatchedHandler, and response assertions in a try/finally block, and move vi.useRealTimers() into the finally so timer state is always restored even if the assertions fail.
377-876: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win考虑拆分测试文件。
本次改动后该文件已明显超过 500 行(新增了 headersProvider/retryPolicy/dedupePolicy/onBusinessResponse 四个较大的 describe 块)。PR 中已有将测试按关注点拆分为独立文件的先例(如
http-client.cooldown.test.ts、http-client.edge-cases.test.ts),建议按同样思路将新增的 describe 块拆分为独立文件(如http-client.headers-provider.test.ts、http-client.dedupe-policy.test.ts等),便于维护。As per coding guidelines, "Consider splitting files that exceed 500 lines into smaller modules" (
**/*.{ts,tsx}).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/web/src/services/api/http-factory/__tests__/http-client.test.ts` around lines 377 - 876, The http-client test file has grown beyond the size guideline and now contains several large, unrelated describe blocks, so split the new coverage into focused test files to improve maintainability. Move the headersProvider, retryPolicy, dedupePolicy, and onBusinessResponse suites out of http-client.test.ts into separate spec files, following the existing pattern used by http-client.cooldown.test.ts and http-client.edge-cases.test.ts, and keep each file centered on one concern while preserving the same test setup helpers and coverage.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@apps/web/src/services/api/http-factory/__tests__/http-client.retry-policy.test.ts`:
- Line 2: The test file has an unused default import from axios that triggers
TS6133 and breaks the build. Update the import in
http-client.retry-policy.test.ts to keep only the used named symbol AxiosError
and remove the axios default import; verify no other references in the test rely
on axios so the import list stays minimal.
In `@apps/web/src/services/api/http-factory/dedupe-manager.ts`:
- Around line 3-6: The interface name in dedupe-manager.ts should follow the
project’s interface naming convention by adding the I prefix. Rename
PendingRequest to IPendingRequest and update all references in the same module,
including the Map<string, PendingRequest> type annotation and any related
usages, so the types stay consistent with the new identifier.
- Around line 76-82: The cleanup in dedupe-manager’s promise handling is
creating an unobserved derived Promise via promise.finally(...), which can
surface as unhandledrejection when the original request rejects. Update the
logic in the dedupe manager to avoid discarding the returned Promise by
switching to a handled cleanup path such as promise.then(cleanup, cleanup), or
otherwise explicitly consume the result of finally() while preserving the
current pending-map guard keyed by key/current.promise.
In `@apps/web/src/services/api/http-factory/types/http-client-options.ts`:
- Around line 141-150: The documentation for isRefreshFailure in
http-client-options.ts is out of sync with the actual default behavior in
defaultIsRefreshFailure. Update the comment for isRefreshFailure so it matches
the real logic: non-Axios errors are treated as refresh failures, and the
existing status-code and authFailureCodes rules remain unchanged. Use the
isRefreshFailure option and defaultIsRefreshFailure symbol to locate the
affected docblock and keep the wording consistent with the implementation.
---
Outside diff comments:
In `@apps/web/src/services/api/http-factory/index.ts`:
- Around line 155-178: `retryAfterRefresh` 里的 catch 会重复触发 `onError` 并二次包装错误,因为
`refreshAccessToken()` 和 `instance.request(config)` 的失败已经在其他拦截器路径里调用过
`invokeOnError`。请在该分支中保留 `normalizeError(error)` 的标准化结果,但直接抛出它,不要再次调用
`invokeOnError`;重点检查 `retryAfterRefresh`、`refreshAccessToken` 和
`instance.request` 这条重试链路,避免重复上报和重复转换。
---
Nitpick comments:
In
`@apps/web/src/services/api/http-factory/__tests__/http-client.refresh.test.ts`:
- Around line 5-15: The axios mock in the http-client.refresh test is redundant
because it only re-exposes the real isAxiosError behavior without changing
anything. Remove the vi.mock("axios", ...) block from the test setup so the
suite uses the actual axios implementation directly, and keep the rest of the
test file unchanged.
- Around line 17-31: The test helper makeAxiosError is duplicated between this
suite and http-client.retry-policy.test.ts, so the error construction logic
should be shared instead of maintained in two places. Move the common AxiosError
factory into a reusable test utility and update http-client.refresh.test.ts to
import it, keeping only the extra code field handling here if needed. Use the
existing makeAxiosError symbol in both tests as the reference point when
extracting the shared helper.
In
`@apps/web/src/services/api/http-factory/__tests__/http-client.retry-policy.test.ts`:
- Around line 21-35: The makeAxiosError helper in
http-client.retry-policy.test.ts duplicates the same AxiosError setup used in
http-client.refresh.test.ts, so extract this shared test utility into a common
test helper and reuse it from both specs. Move the reusable helper into a shared
location near the existing http-client test helpers, then update the
retry-policy and refresh tests to import and call that shared function instead
of maintaining separate copies.
- Around line 9-19: The axios mock in the http-client retry policy test is
redundant because it simply recreates the real module without changing behavior.
Remove the vi.mock("axios", ...) setup from the retry-policy test file and keep
the test using the actual axios export behavior, matching the approach used in
http-client.refresh.test.ts.
In `@apps/web/src/services/api/http-factory/__tests__/http-client.test.ts`:
- Around line 856-868: The test mock in onBusinessResponse uses a field-level
any cast on config, which violates the no-any rule. Update the
http-client.test.ts fixture in the onBusinessResponse case by typing the whole
mocked AxiosResponse object with the existing AxiosResponse type (or an
equivalent project type) instead of using config: {} as any, so the
createHttpClient test remains type-safe without any.
- Around line 608-646: Test case in http-client.test.ts uses vi.useFakeTimers()
without guaranteed cleanup, so a failure before the end leaves fake timers
enabled for later tests. Wrap the body of the retry test around the
createHttpClient, queueMatchedHandler, and response assertions in a try/finally
block, and move vi.useRealTimers() into the finally so timer state is always
restored even if the assertions fail.
- Around line 377-876: The http-client test file has grown beyond the size
guideline and now contains several large, unrelated describe blocks, so split
the new coverage into focused test files to improve maintainability. Move the
headersProvider, retryPolicy, dedupePolicy, and onBusinessResponse suites out of
http-client.test.ts into separate spec files, following the existing pattern
used by http-client.cooldown.test.ts and http-client.edge-cases.test.ts, and
keep each file centered on one concern while preserving the same test setup
helpers and coverage.
In `@apps/web/src/services/api/http-factory/__tests__/http-client.token.test.ts`:
- Around line 42-116: 测试用例里多处通过 as any 绕过了类型检查,违反了禁止 any 的规范。请在
http-client.token.test.ts 中的 normalizeTokenResult
相关断言里,改用更精确的类型断言或直接构造符合项目类型定义的输入,优先复用 AccessTokenResult 等已有类型,避免 any 出现在测试代码中。
In `@apps/web/src/services/api/http-factory/types/common.ts`:
- Around line 6-11: Rename the interface types in common.ts to match the
repository’s `I`-prefix convention: change `RequestRetryState`, `ErrorContext`,
and `ErrorMessages` to `IRequestRetryState`, `IErrorContext`, and
`IErrorMessages`. Update any references to these symbols across the related HTTP
factory types and usages so the renamed interfaces remain consistent and compile
cleanly.
In `@apps/web/src/services/api/http-factory/types/http-client-options.ts`:
- Around line 13-29: Rename the interface types to follow the repository’s
`I`-prefixed PascalCase convention: change `DedupePolicy`, `RetryPolicy`, and
`HttpClientOptions` to `IDedupePolicy`, `IRetryPolicy`, and `IHttpClientOptions`
in the `http-client-options` types module. Update any related references in the
same file and nearby type usages so the exported API and all consumers continue
to compile with the new names.
In `@apps/web/src/services/api/http-factory/types/token.ts`:
- Around line 4-7: The interface name does not follow the repository’s `I`
prefix convention. Update the `AccessTokenDetail` interface in `token.ts` to use
the required interface naming style, and make sure any references to
`AccessTokenDetail` elsewhere are renamed to match the new `IAccessTokenDetail`
symbol.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 04fc2344-d2fb-49dd-877e-9934265cca3f
📒 Files selected for processing (24)
.codegraph/.gitignoreCLAUDE.mdapps/web/src/pages/cache-capabilities/index.tsxapps/web/src/services/api/http-factory/__tests__/http-client.cooldown.test.tsapps/web/src/services/api/http-factory/__tests__/http-client.edge-cases.test.tsapps/web/src/services/api/http-factory/__tests__/http-client.error.test.tsapps/web/src/services/api/http-factory/__tests__/http-client.refresh.test.tsapps/web/src/services/api/http-factory/__tests__/http-client.retry-policy.test.tsapps/web/src/services/api/http-factory/__tests__/http-client.test.tsapps/web/src/services/api/http-factory/__tests__/http-client.token.test.tsapps/web/src/services/api/http-factory/constants.tsapps/web/src/services/api/http-factory/dedupe-manager.tsapps/web/src/services/api/http-factory/index.tsapps/web/src/services/api/http-factory/reference/README.mdapps/web/src/services/api/http-factory/reference/http-demo.tsapps/web/src/services/api/http-factory/token-refresh-manager.tsapps/web/src/services/api/http-factory/types.tsapps/web/src/services/api/http-factory/types/common.tsapps/web/src/services/api/http-factory/types/http-client-options.tsapps/web/src/services/api/http-factory/types/token.tsapps/web/src/services/api/http-factory/utils/error.tsapps/web/src/services/api/http-factory/utils/refresh.tsapps/web/src/services/api/http-factory/utils/token.tsapps/web/src/services/api/new-http.ts
💤 Files with no reviewable changes (1)
- apps/web/src/services/api/http-factory/types.ts
…nhandledrejection,同步 isRefreshFailure 注释 - PendingRequest → IPendingRequest,接口加 I 前缀 - promise.finally() → void promise.then(cleanup, cleanup),避免派生 Promise 未消费导致 unhandledrejection - isRefreshFailure JSDoc 同步修正为「非 AxiosError 视为刷新失败」
… in refresh utility
Summary
defaultIsRefreshFailure非 AxiosError(如业务代码抛出的 Error)现在正确视为鉴权失败,触发onAuthFailure;网络错误 / 500 服务端错误仍不视为鉴权失败改动文件
utils/refresh.ts— 修复defaultIsRefreshFailure,非 AxiosError 返回true__tests__/http-client.error.test.ts— 新增,normalizeError / invokeOnError 单元测试__tests__/http-client.refresh.test.ts— 新增,shouldSkipRefresh / defaultIsRefreshFailure 单元测试__tests__/http-client.retry-policy.test.ts— 新增,defaultShouldRetry / defaultRetryDelay / resolveRetryPolicy 单元测试__tests__/http-client.token.test.ts— 新增,formatAccessToken / normalizeTokenResult 单元测试__tests__/http-client.test.ts— 新增 3 个 integration 测试__tests__/http-client.edge-cases.test.ts— 修复 3 个断言(对齐修复后行为)__tests__/http-client.cooldown.test.ts— 场景 6 网络错误改用 AxiosError(更贴近真实场景)reference/http-demo.ts— 补充新功能示例,移除冗余自定义 isRefreshFailurereference/README.md— 全量更新文档Test plan
npx vitest run apps/web/src/services/api/http-factory/__tests__/全部 119 个测试通过Summary by CodeRabbit
新功能
Bug 修复
文档