Skip to content

fix: prevent duplicate channel action toasts - #5015

Merged
seefs001 merged 3 commits into
QuantumNous:mainfrom
yyhhyyyyyy:fix/channel-duplicate-toast
May 26, 2026
Merged

fix: prevent duplicate channel action toasts#5015
seefs001 merged 3 commits into
QuantumNous:mainfrom
yyhhyyyyyy:fix/channel-duplicate-toast

Conversation

@yyhhyyyyyy

@yyhhyyyyyy yyhhyyyyyy commented May 21, 2026

Copy link
Copy Markdown
Contributor

⚠️ 提交说明 / 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

    • Enhanced error messaging when channel operations fail, displaying response-based error details.
    • Improved error feedback for key status loading and model application failures.
    • Refined batch operation success/failure counting logic.
  • Improvements

    • Centralized error handling configuration for channel and upstream update operations.
    • Optimized GET request deduplication caching.
    • Enhanced session expiration handling with user-friendly messaging.

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 21, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

Failed to post review comments

Walkthrough

This PR centralizes error handling configuration across the channel management system by introducing typed request control flags (skipBusinessError, skipErrorHandler, disableDuplicate) and refactoring API calls to use shared configuration helpers instead of inline configs. It ensures that error messages from the API are propagated consistently without duplication.

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 three new optional control flags: skipBusinessError, skipErrorHandler, and disableDuplicate. ApiRequestConfig is exported as a public type alias. The api.get wrapper now reads disableDuplicate from config and builds deduplication cache keys from url plus JSON-stringified params. The response interceptor checks response.config.skipBusinessError directly to determine whether to suppress automatic error toasts. The error interceptor is refactored to handle 401 auth resets via useAuthStore.getState().auth.reset() separately from other errors, showing a Session expired! toast unless skipErrorHandler is set, and conditionally toasting messages from error.response.data.message, error.message, or a fallback Request failed for non-401 errors.
Centralized channel operation request configuration
web/default/src/features/channels/api.ts
Introduces channelActionConfig helper that returns an ApiRequestConfig with skipBusinessError and skipErrorHandler enabled. All channel operations (create, update, delete, batch delete, batch tag operations, test, balance updates, model fetching, copy, fix abilities, key management, tag enable/disable, model operations) are refactored to pass channelActionConfig() into their api calls. Codex OAuth operations and Codex usage retrieval also use the helper, with the usage endpoint additionally setting disableDuplicate: true to prevent cache collisions. The obsolete local ExtendedApiConfig type is removed.
Upstream update request configuration centralization
web/default/src/features/channels/hooks/use-channel-upstream-updates.ts
Adds upstreamUpdateRequestConfig helper with skipBusinessError and skipErrorHandler enabled. Four upstream-update endpoints (apply, apply_all, detect, detect_all) are updated to use the centralized config instead of inline skipErrorHandler: true objects.
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
Channel action handlers now consistently prefer response.message (with localized fallback) for error toasts across enable, disable, delete, batch operations, and tag operations. Batch enable/disable success/failure counting is corrected to treat a fulfilled result as success only when the resolved value includes success: true, with failCount computed as the remainder. Multi-key dialog's loadKeyStatus error path is adjusted with an explicit else branch. Ollama models dialog's applySelection wraps updateChannel in try/catch to capture both thrown errors and response-based failures, displaying appropriate error toasts in each case.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • QuantumNous/new-api#1498: Both PRs target the multi-key management "key status" flow: the retrieved PR adds the /multi_key/manage backend handler and multi-key UI/modal, while this PR updates the frontend loadKeyStatus failure path and request config for that same key-status retrieval.

Suggested reviewers

  • seefs001

Poem

🐰 A rabbit hops through error toasts so bright,
No more double-bouncing in the night!
One message flows from API to view,
Config helpers keep the handlers true. ✨

🚥 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 accurately summarizes the main change: preventing duplicate channel action toasts through centralized API request configuration and error handling.
Linked Issues check ✅ Passed The PR fully addresses issue #5013 by adding skipBusinessError/skipErrorHandler flags to channel requests, centralizing error toasts in handlers, and preserving 401 authentication cleanup across all affected operations.
Out of Scope Changes check ✅ Passed All changes are directly related to resolving duplicate toast notifications in channel management. The modifications to api.ts, channel-actions.ts, api.ts, and related files focus solely on implementing the required error handling mechanism.
Docstring Coverage ✅ Passed Docstring coverage is 80.49% 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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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

seefs001
seefs001 previously approved these changes May 25, 2026
@seefs001
seefs001 merged commit ad224ec into QuantumNous:main May 26, 2026
1 check passed
52assert added a commit to 52assert/new-api that referenced this pull request May 28, 2026
…codes

* origin/main: (34 commits)
  fix: optimize batch update process
  fix: keep token log filters exact
  fix: keep usage log filters exact unless wildcard is explicit (QuantumNous#5097)
  fix(web): improve channel and usage log UI
  feat(theme): add simple-large preset, xl scale and clean up channel badge dots
  🐛 fix(system-settings): resolve save detection and number input NaN issues
  🎨 fix(logs): tune usage table typography
  fix: use actual user id for channel tests (QuantumNous#5109)
  fix: consolidate Waffo payment settings save flow (QuantumNous#5110)
  🎨 fix(charts): improve dark mode chart readability
  🎨 fix(logs): remove hardcoded font-mono to support global theme font inheritance
  🎨 fix(logs): restore timing background badges and optimize model/token spacing
  feat(subscription): support balance purchases
  🎨 fix(theme): default theme font preset falls back to Sans instead of Serif
  🎨 refactor(badge): restore status-badge sizes and classic color scheme
  fix: prevent duplicate channel action toasts (QuantumNous#5015)
  🎨 feat(web/default): add Anthropic theme preset and configurable serif typography
  ♻️ refactor(channels): rebuild channel editor UX with modular sections and Base UI multi-select
  ♻️ refactor(channels): rebuild channel create/edit drawer with modular sections and improved form UX
  fix: handle paginated API key search response (QuantumNous#5014)
  ...

# Conflicts:
#	controller/misc.go
#	web/default/src/features/auth/sign-in/components/user-auth-form.tsx
#	web/default/src/features/auth/sign-in/index.tsx
#	web/default/src/features/auth/sign-up/components/sign-up-form.tsx
#	web/default/src/hooks/use-sidebar-data.ts
#	web/default/src/routes/__root.tsx
xyfacai pushed a commit to xyfacai/new-api that referenced this pull request May 30, 2026
* fix: prevent duplicate channel action toasts

* fix: localize api error fallbacks
ySion pushed a commit to FrostFoxAtelier/new-api that referenced this pull request May 31, 2026
* fix: prevent duplicate channel action toasts

* fix: localize api error fallbacks
SamuelSxy pushed a commit to SamuelSxy/new-api-rh that referenced this pull request Jun 7, 2026
* fix: prevent duplicate channel action toasts

* fix: localize api error fallbacks
fx247562340 pushed a commit to fx247562340/vancine-platform that referenced this pull request Jun 11, 2026
* fix: prevent duplicate channel action toasts

* fix: localize api error fallbacks
330079598 pushed a commit to 330079598/new-api that referenced this pull request Aug 19, 2026
* fix: prevent duplicate channel action toasts

* fix: localize api error fallbacks
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 弹出两次

2 participants