Skip to content

fix: prevent duplicate channel action toasts#5015

Open
yyhhyyyyyy wants to merge 2 commits into
QuantumNous:mainfrom
yyhhyyyyyy:fix/channel-duplicate-toast
Open

fix: prevent duplicate channel action toasts#5015
yyhhyyyyyy wants to merge 2 commits into
QuantumNous:mainfrom
yyhhyyyyyy:fix/channel-duplicate-toast

Conversation

@yyhhyyyyyy
Copy link
Copy Markdown
Contributor

@yyhhyyyyyy yyhhyyyyyy commented May 21, 2026

⚠️ 提交说明 / PR Notice

Important

  • 请提供人工撰写的简洁摘要,避免直接粘贴未经整理的 AI 输出。

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)
修复default 前端渠道管理操作失败时 toast 重复弹出。根因是 api.ts 全局响应拦截器会对业务错误/HTTP 错误统一提示,而渠道管理的操作层也会根据返回结果自行提示,导致同一次失败出现两条错误通知。
本次将渠道管理的用户动作请求统一标记为由调用方处理错误,跳过全局错误 toast,并补齐对应调用点的本地失败处理。同时保留 401 登录态清理逻辑,避免跳过全局提示后影响认证状态一致性。

🚀 变更类型 / Type of change

  • 🐛 Bug 修复 (Bug fix) - 请关联对应 Issue,避免将设计取舍、理解偏差或预期不一致直接归类为 bug
  • ✨ 新功能 (New feature) - 重大特性建议先通过 Issue 沟通
  • ⚡ 性能优化 / 重构 (Refactor)
  • 📝 文档更新 (Documentation)

🔗 关联任务 / Related Issue

✅ 提交前检查项 / Checklist

  • 人工确认: 我已亲自整理并撰写此描述,没有直接粘贴未经处理的 AI 输出。
  • 非重复提交: 我已搜索现有的 IssuesPRs,确认不是重复提交。
  • Bug fix 说明: 若此 PR 标记为 Bug fix,我已提交或关联对应 Issue,且不会将设计取舍、预期不一致或理解偏差直接归类为 bug。
  • 变更理解: 我已理解这些更改的工作原理及可能影响。
  • 范围聚焦: 本 PR 未包含任何与当前任务无关的代码改动。
  • 本地验证: 已在本地运行并通过测试或手动验证,维护者可以据此复核结果。
  • 安全合规: 代码中无敏感凭据,且符合项目代码规范。

📸 运行证明 / Proof of Work

(请在此粘贴截图、关键日志或测试报告,以证明变更生效)

iShot_2026-05-21_16.14.15.mp4

Summary by CodeRabbit

  • Bug Fixes

    • Improved error messages and toasts across channel flows (key status, model application, create/update, batch enable/disable).
    • Failures now consistently halt submission and surface clear error feedback.
    • Session-expiry and request-failure handling now show more reliable notifications.
  • Refactor

    • Centralized API request options to ensure consistent error-handling behavior and deduplication across channel actions.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

Walkthrough

This PR centralizes channel API request configuration and error handling to eliminate duplicate error toasts. It introduces typed request control flags (skipBusinessError, skipErrorHandler, disableDuplicate) in the shared API layer, applies them consistently across channel and upstream operations via helper functions, and ensures API error messages propagate once through action handlers to users.

Changes

Centralized Channel API Error Handling & Request Configuration

Layer / File(s) Summary
API layer type extensions and error interceptor refactoring
web/default/src/lib/api.ts
AxiosRequestConfig is augmented with typed control flags; ApiRequestConfig type alias is exported; api.get deduplication logic is refactored to use typed config; error interceptor branches on 401 for auth reset separate from other errors, with conditional toast messaging for each.
Centralized channel operation request configuration
web/default/src/features/channels/api.ts
channelActionConfig helper centralizes skipBusinessError and skipErrorHandler flags; all channel operations (create/update/delete, batch actions, tests, balance, models, copy, fix, key, Codex OAuth, tag operations) refactored to use the helper; ExtendedApiConfig removed.
Upstream update request configuration centralization
web/default/src/features/channels/hooks/use-channel-upstream-updates.ts
upstreamUpdateRequestConfig helper added; four upstream-update API calls refactored to use centralized config instead of inline skipErrorHandler settings.
Error message consistency and component error handling
web/default/src/features/channels/lib/channel-actions.ts, web/default/src/features/channels/components/dialogs/multi-key-manage-dialog.tsx, web/default/src/features/channels/components/dialogs/ollama-models-dialog.tsx, web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
Channel action handlers updated to report response.message with fallback to localized text; batch enable/disable recomputed to count fulfilled success-only results; component error paths adjusted (else branch scoping, try/catch wrapping, explicit throws) to ensure errors surface once with server-provided context.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • QuantumNous/new-api#1498: Implements multi-key management endpoints and UI, directly overlapping with this PR's multi-key dialog error-handling updates.
  • QuantumNous/new-api#1653: Introduces channel key access flow (GetChannelKey + 2FA modal), same feature surface that this PR's channelActionConfig now covers for key retrieval requests.

Suggested reviewers

  • seefs001

Poem

🐇 Errors bouncing, doubly crowned,
Now one toast per failure sound,
Config centralized, bright and clean,
Where only one message should be seen! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: prevent duplicate channel action toasts' directly and concisely summarizes the primary change: eliminating duplicate error toasts in channel operations.
Linked Issues check ✅ Passed The PR comprehensively addresses all coding requirements from issue #5013: centralizes API request configuration with skipBusinessError/skipErrorHandler flags across channel operations, adds local error handling at call sites, preserves 401 authentication handling, and applies changes to all affected entry points.
Out of Scope Changes check ✅ Passed All code changes directly support the objective to prevent duplicate toasts by centralizing API request configuration and error handling in channel-related features; no unrelated modifications detected.
Docstring Coverage ✅ Passed Docstring coverage is 80.95% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 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 `@web/default/src/lib/api.ts`:
- Around line 19-20: Replace the default i18next import with the non-React named
import (import { t } from 'i18next') at the top of the module and convert all
user-facing fallback strings in this file to use t(...) instead of hard-coded
text; specifically replace literals like "Request failed" and "Request error"
(and any other fallbacks in the error-building functions such as
normalizeErrorMessage / getErrorMessage / handleApiError or module-level default
message constants between lines ~80-117) with i18n keys (e.g.
t('errors.requestFailed'), t('errors.requestError')) so every user-visible
message uses t() and follows the repo standard import.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6d55fbb4-16bc-4eed-a25d-ed786d551295

📥 Commits

Reviewing files that changed from the base of the PR and between 006e801 and 81719d4.

📒 Files selected for processing (7)
  • web/default/src/features/channels/api.ts
  • web/default/src/features/channels/components/dialogs/multi-key-manage-dialog.tsx
  • web/default/src/features/channels/components/dialogs/ollama-models-dialog.tsx
  • web/default/src/features/channels/components/drawers/channel-mutate-drawer.tsx
  • web/default/src/features/channels/hooks/use-channel-upstream-updates.ts
  • web/default/src/features/channels/lib/channel-actions.ts
  • web/default/src/lib/api.ts

Comment thread web/default/src/lib/api.ts Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
web/default/src/lib/api.ts (1)

63-72: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Include the per-request error flags in the GET dedupe identity.

The dedupe key still only uses url + params, so two concurrent api.get calls with different skipBusinessError / skipErrorHandler values collapse onto one promise. That makes the first caller’s config decide whether the interceptor toasts, which can suppress or reintroduce duplicate channel toasts depending on call order.

Suggested fix
-  const params = config.params ? JSON.stringify(config.params) : '{}'
-  const key = `${url}?${params}`
+  const params = config.params ? JSON.stringify(config.params) : '{}'
+  const key = JSON.stringify({
+    url,
+    params,
+    skipBusinessError: !!config.skipBusinessError,
+    skipErrorHandler: !!config.skipErrorHandler,
+  })
🤖 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 `@web/default/src/lib/api.ts` around lines 63 - 72, The dedupe key used by
inFlightGet only includes url and params so concurrent api.get calls with
different per-request flags (skipBusinessError / skipErrorHandler) collapse;
update the key generation (where params and key are built for inFlightGet) to
incorporate those boolean flags from the config (e.g., include
config.skipBusinessError and config.skipErrorHandler in the stringified
identity) so that inFlightGet.lookup, set, and deletion around originalGet
preserve distinct promises for different flag combinations.
🤖 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.

Outside diff comments:
In `@web/default/src/lib/api.ts`:
- Around line 63-72: The dedupe key used by inFlightGet only includes url and
params so concurrent api.get calls with different per-request flags
(skipBusinessError / skipErrorHandler) collapse; update the key generation
(where params and key are built for inFlightGet) to incorporate those boolean
flags from the config (e.g., include config.skipBusinessError and
config.skipErrorHandler in the stringified identity) so that inFlightGet.lookup,
set, and deletion around originalGet preserve distinct promises for different
flag combinations.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: fc277ffe-e6b3-4d8e-a631-13a85502d4c5

📥 Commits

Reviewing files that changed from the base of the PR and between 81719d4 and 904f640.

📒 Files selected for processing (1)
  • web/default/src/lib/api.ts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

渠道测试连接失败时错误 Toast 弹出两次

1 participant