Skip to content

修复了一些连接上的BUG - #5181

Closed
sdfsdfw2 wants to merge 8 commits into
QuantumNous:mainfrom
sdfsdfw2:main
Closed

修复了一些连接上的BUG#5181
sdfsdfw2 wants to merge 8 commits into
QuantumNous:mainfrom
sdfsdfw2:main

Conversation

@sdfsdfw2

@sdfsdfw2 sdfsdfw2 commented May 29, 2026

Copy link
Copy Markdown

⚠️ 提交说明 / PR Notice

Important

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

📝 变更描述 / Description

(简述:做了什么?为什么这样改能生效?请基于你对代码逻辑的理解来写,避免粘贴未经整理的内容)

🚀 变更类型 / Type of change

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

🔗 关联任务 / Related Issue

  • Closes # (如有)

✅ 提交前检查项 / Checklist

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

📸 运行证明 / Proof of Work

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

Summary by CodeRabbit

Release Notes

  • New Features

    • Automatic channel deletion feature: Enable global toggle and configure keywords to automatically delete channels when upstream errors contain matches, taking priority over disabling behavior
    • Added relay response header timeout configuration for improved connection management
  • Infrastructure

    • Optimized Docker build by removing integrated frontend compilation stages

Review Change Stack

@coderabbitai

coderabbitai Bot commented May 29, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

This PR adds automatic channel deletion triggered by upstream error keywords. Channels can now be configured to delete when request failures match configured deletion keywords, with deletion taking priority over the existing disable-on-error behavior. The frontend build stages are also removed from the Docker image.

Changes

Automatic Channel Deletion Feature

Layer / File(s) Summary
Docker build cleanup
.dockerignore, Dockerfile
Removed Bun-based multi-stage frontend builds that previously compiled web/default and web/classic assets before the Go build.
Configuration constants and initialization
common/constants.go, common/init.go, setting/operation_setting/operation_setting.go
Added AutomaticDeleteChannelEnabled flag and RelayResponseHeaderTimeout constant; created AutomaticDeleteKeywords slice with ToString() and FromString() helpers for newline-separated serialization.
Service-layer deletion functions
service/channel.go, model/channel.go
Implemented ShouldDeleteChannel() to check deletion eligibility against error messages and keywords, and DeleteChannel() to delete the channel, clear cache, and notify the root user.
Error handling pathway integration
controller/relay.go, controller/channel-test.go
Modified error handlers to call ShouldDeleteChannel() first; when true, invoke DeleteChannel() instead of the disable path; skips disable processing after deletion to avoid redundant actions.
Option system wiring
model/option.go
Extended runtime option initialization and update handlers to expose deletion flag and keyword list through the admin options interface.
HTTP client transport formatting
service/http_client.go
Reformatted http.Transport field order in default, proxy, and SOCKS client initializations for consistency; no functional changes to timeout or proxy behavior.
Classic UI form controls
web/classic/src/components/settings/OperationSetting.jsx, web/classic/src/pages/Setting/Operation/SettingsMonitoring.jsx
Added deletion flag switch and keyword textarea to the monitoring settings form with component state binding and existing diff-based save flow integration.
Default UI type definitions and defaults
web/default/src/features/system-settings/types.ts, web/default/src/features/system-settings/operations/index.tsx, web/default/src/features/system-settings/operations/section-registry.tsx
Extended OperationsSettings type with AutomaticDeleteChannelEnabled and AutomaticDeleteKeywords fields; provided defaults and registry forwarding to the monitoring section component.
Default UI form schema and normalization
web/default/src/features/system-settings/integrations/monitoring-settings-section.tsx
Updated Zod schema to include deletion fields, extended normalization helpers (buildFormDefaults, normalizeDefaults, normalizeFormValues) to handle line-ending normalization, and added UI switch and textarea with help text indicating deletion priority over disabling.
Internationalization
web/default/src/i18n/locales/{en,fr,ja,ru,vi,zh}.json
Added translated strings for "automatically delete channels when failure keywords match," deletion control labels, and clarification that deletion takes priority over disabling, across all six supported language locales.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • QuantumNous/new-api#2669: Both PRs modify controller/relay.go's processChannelError flow—main PR changes error handling to delete vs disable channels, while retrieved PR augments the same error/admin_info payload with channel-affinity data—so the changes are related at the code level.
  • QuantumNous/new-api#2194: Both PRs modify controller/relay.go's processChannelError decision logic around calling service.ShouldDisableChannel(...) (and, in the main PR, choosing between disabling vs deleting), so the changes are code-level related.
  • QuantumNous/new-api#2647: Main PR's channel-error handling now chooses between auto-deletion (ShouldDeleteChannel) and fallback auto-disabling (ShouldDisableChannel), and the retrieved PR directly changes ShouldDisableChannel to add early "disable-by-status-code" logic—so the disabling branch they modify is the same decision point used by the main PR.

Suggested reviewers

  • seefs001

🐰 Channels now learn to vanish when keywords whisper,
A fleeting dance of auto-delete, precise and swift,
Configuration blooms on both UIs bright,
While Docker builds shed their Bun-built weight,
And locales sing the deletion song across the globe.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Title check ⚠️ Warning The PR title '修复了一些连接上的BUG' (Fixed some connection bugs) is vague and does not accurately reflect the primary changes. The PR implements automatic channel deletion features, timeout configurations, Docker changes, and UI updates—not just general connection bug fixes. Revise the title to accurately describe the main feature being introduced, such as 'Add automatic channel deletion on error keywords' or similar, rather than using generic 'bug fixes' language.
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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

🧹 Nitpick comments (4)
setting/operation_setting/operation_setting.go (2)

34-50: 💤 Low value

Optional: deduplicate the keyword serialize/parse helpers.

These three additions are an exact copy of the AutomaticDisableKeywords variants. A small shared helper that operates on a *[]string would remove the copy-paste and keep both in sync.

♻️ Possible shared helper
func keywordsToString(kw []string) string {
	return strings.Join(kw, "\n")
}

func keywordsFromString(s string) []string {
	out := []string{}
	for _, k := range strings.Split(s, "\n") {
		k = strings.ToLower(strings.TrimSpace(k))
		if k != "" {
			out = append(out, k)
		}
	}
	return out
}

Then AutomaticDeleteKeywordsFromString becomes AutomaticDeleteKeywords = keywordsFromString(s).

🤖 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 `@setting/operation_setting/operation_setting.go` around lines 34 - 50, The
AutomaticDeleteKeywords serialization/parsing (AutomaticDeleteKeywordsToString,
AutomaticDeleteKeywordsFromString) duplicate logic already present for
AutomaticDisableKeywords; create a small shared helper pair (e.g.,
keywordsToString(kw []string) string and keywordsFromString(s string) []string
or a helper that accepts *[]string) and replace AutomaticDeleteKeywordsToString
to call keywordsToString(AutomaticDeleteKeywords) and
AutomaticDeleteKeywordsFromString to assign AutomaticDeleteKeywords =
keywordsFromString(s) so both keyword sets reuse the same normalized
join/split/trimming/lowercasing logic.

40-50: ⚡ Quick win

Delete-keyword matching is case-insensitive already.

AutomaticDeleteKeywordsFromString lowercases stored keywords, and service/channel.go’s ShouldDeleteChannel lowercases err.Error() (strings.ToLower(err.Error())) before matching against operation_setting.AutomaticDeleteKeywords, so uppercase in the upstream error won’t prevent matches.
Optional: AutomaticDisableKeywordsFromString and AutomaticDeleteKeywordsFromString are identical—could be factored to avoid copy-paste.

🤖 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 `@setting/operation_setting/operation_setting.go` around lines 40 - 50, The
current behavior already lowercases keywords so matching is case-insensitive; to
remove duplication, extract the shared logic into a helper like
parseKeywordsFromString(s string) []string that trims, lowercases and filters
empty lines, then update AutomaticDeleteKeywordsFromString and
AutomaticDisableKeywordsFromString to call this helper and assign the result to
AutomaticDeleteKeywords/AutomaticDisableKeywords respectively; ensure the helper
is referenced from those functions (AutomaticDeleteKeywordsFromString,
AutomaticDisableKeywordsFromString) so the duplicate loop is removed.
web/default/src/features/system-settings/integrations/monitoring-settings-section.tsx (1)

417-440: 💤 Low value

Consider reusing SettingsSwitchItem for visual consistency.

The sibling switches (AutomaticDisableChannelEnabled, AutomaticEnableChannelEnabled, scheduled tests) use SettingsSwitchItem/SettingsSwitchContent, while this new switch hand-rolls a FormItem with manual flex/border classes. Aligning with the shared component keeps styling consistent and reduces drift.

🤖 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/features/system-settings/integrations/monitoring-settings-section.tsx`
around lines 417 - 440, Replace the hand-rolled FormField/FormItem for the
AutomaticDeleteChannelEnabled switch with the shared
SettingsSwitchItem/SettingsSwitchContent components to match sibling switches;
locate the FormField with name 'AutomaticDeleteChannelEnabled' and swap its
render to use SettingsSwitchItem (pass the label "Delete on keyword match") and
SettingsSwitchContent (pass the description "Automatically delete channels when
failure keywords match"), wiring the form control/value by connecting the
Switch's checked to field.value and onCheckedChange to field.onChange so
behavior stays the same and visual styling is consistent with
AutomaticDisableChannelEnabled/AutomaticEnableChannelEnabled.
service/channel.go (1)

99-102: 💤 Low value

Log message refers to "auto-disable" but should mention "auto-delete" or "auto-ban".

The log message on line 100 says 未启用自动禁用功能,跳过删除操作 ("auto-disable function not enabled, skipping delete operation"). The first part mentions "auto-disable" (自动禁用) but the operation being skipped is deletion. For consistency, consider updating the message to refer to "automatic channel management" (自动管理功能) or "auto-ban" (自动禁用) more generically, since AutoBan gates both disabling and deletion.

Suggested clarification
-		common.SysLog(fmt.Sprintf("通道「%s」(#%d)未启用自动禁用功能,跳过删除操作", channelError.ChannelName, channelError.ChannelId))
+		common.SysLog(fmt.Sprintf("通道「%s」(#%d)未启用自动管理功能,跳过删除操作", channelError.ChannelName, channelError.ChannelId))
🤖 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 `@service/channel.go` around lines 99 - 102, Update the log message in the
common.SysLog call that references channelError.AutoBan to correctly reflect the
guarded behavior: change the current message that says "未启用自动禁用功能,跳过删除操作" to
something like "未启用自动管理功能(自动禁用/删除),跳过删除操作" or explicitly "未启用自动禁用/删除功能,跳过删除操作"
so it consistently refers to both ban and delete; edit the string passed to
common.SysLog in the block that checks channelError.AutoBan (using
channelError.ChannelName and channelError.ChannelId) to the new wording.
🤖 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 `@model/channel.go`:
- Around line 875-881: Rename the misleading function DeleteChannelByStatusAndId
to DeleteChannelById and update its signature/usage accordingly: keep the
implementation that loads a Channel by ID and calls channel.Delete(), and remove
any expectation of a status parameter (the status-based logic remains in
DeleteChannelByStatus); then find and update all call sites that reference
DeleteChannelByStatusAndId (e.g., in the channel service layer) to call
DeleteChannelById instead so names accurately reflect behavior.

---

Nitpick comments:
In `@service/channel.go`:
- Around line 99-102: Update the log message in the common.SysLog call that
references channelError.AutoBan to correctly reflect the guarded behavior:
change the current message that says "未启用自动禁用功能,跳过删除操作" to something like
"未启用自动管理功能(自动禁用/删除),跳过删除操作" or explicitly "未启用自动禁用/删除功能,跳过删除操作" so it
consistently refers to both ban and delete; edit the string passed to
common.SysLog in the block that checks channelError.AutoBan (using
channelError.ChannelName and channelError.ChannelId) to the new wording.

In `@setting/operation_setting/operation_setting.go`:
- Around line 34-50: The AutomaticDeleteKeywords serialization/parsing
(AutomaticDeleteKeywordsToString, AutomaticDeleteKeywordsFromString) duplicate
logic already present for AutomaticDisableKeywords; create a small shared helper
pair (e.g., keywordsToString(kw []string) string and keywordsFromString(s
string) []string or a helper that accepts *[]string) and replace
AutomaticDeleteKeywordsToString to call
keywordsToString(AutomaticDeleteKeywords) and AutomaticDeleteKeywordsFromString
to assign AutomaticDeleteKeywords = keywordsFromString(s) so both keyword sets
reuse the same normalized join/split/trimming/lowercasing logic.
- Around line 40-50: The current behavior already lowercases keywords so
matching is case-insensitive; to remove duplication, extract the shared logic
into a helper like parseKeywordsFromString(s string) []string that trims,
lowercases and filters empty lines, then update
AutomaticDeleteKeywordsFromString and AutomaticDisableKeywordsFromString to call
this helper and assign the result to
AutomaticDeleteKeywords/AutomaticDisableKeywords respectively; ensure the helper
is referenced from those functions (AutomaticDeleteKeywordsFromString,
AutomaticDisableKeywordsFromString) so the duplicate loop is removed.

In
`@web/default/src/features/system-settings/integrations/monitoring-settings-section.tsx`:
- Around line 417-440: Replace the hand-rolled FormField/FormItem for the
AutomaticDeleteChannelEnabled switch with the shared
SettingsSwitchItem/SettingsSwitchContent components to match sibling switches;
locate the FormField with name 'AutomaticDeleteChannelEnabled' and swap its
render to use SettingsSwitchItem (pass the label "Delete on keyword match") and
SettingsSwitchContent (pass the description "Automatically delete channels when
failure keywords match"), wiring the form control/value by connecting the
Switch's checked to field.value and onCheckedChange to field.onChange so
behavior stays the same and visual styling is consistent with
AutomaticDisableChannelEnabled/AutomaticEnableChannelEnabled.
🪄 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: 30176b72-f5f7-4cbe-a493-71b0bfa09943

📥 Commits

Reviewing files that changed from the base of the PR and between 1588027 and 27e4858.

⛔ Files ignored due to path filters (1)
  • new-api.tar is excluded by !**/*.tar
📒 Files selected for processing (31)
  • .dockerignore
  • Dockerfile
  • common/constants.go
  • common/init.go
  • controller/channel-test.go
  • controller/relay.go
  • model/channel.go
  • model/option.go
  • service/channel.go
  • service/http_client.go
  • setting/operation_setting/operation_setting.go
  • web/classic/src/components/settings/OperationSetting.jsx
  • web/classic/src/i18n/locales/en.json
  • web/classic/src/i18n/locales/fr.json
  • web/classic/src/i18n/locales/ja.json
  • web/classic/src/i18n/locales/ru.json
  • web/classic/src/i18n/locales/vi.json
  • web/classic/src/i18n/locales/zh-CN.json
  • web/classic/src/i18n/locales/zh-TW.json
  • web/classic/src/i18n/locales/zh.json
  • web/classic/src/pages/Setting/Operation/SettingsMonitoring.jsx
  • web/default/src/features/system-settings/integrations/monitoring-settings-section.tsx
  • web/default/src/features/system-settings/operations/index.tsx
  • web/default/src/features/system-settings/operations/section-registry.tsx
  • web/default/src/features/system-settings/types.ts
  • web/default/src/i18n/locales/en.json
  • web/default/src/i18n/locales/fr.json
  • web/default/src/i18n/locales/ja.json
  • web/default/src/i18n/locales/ru.json
  • web/default/src/i18n/locales/vi.json
  • web/default/src/i18n/locales/zh.json
💤 Files with no reviewable changes (2)
  • .dockerignore
  • Dockerfile

Comment thread model/channel.go
Comment on lines +875 to +881
func DeleteChannelByStatusAndId(channelId int) error {
var channel Channel
if err := DB.First(&channel, channelId).Error; err != nil {
return err
}
return channel.Delete()
}

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.

🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win

Misleading function name: no status parameter despite "ByStatusAndId" naming.

The function is named DeleteChannelByStatusAndId but only accepts channelId as a parameter—there is no status parameter or status-based filtering. This is inconsistent with the existing DeleteChannelByStatus(status int64) on line 870, which does filter by status. The current implementation simply loads a channel by ID and deletes it.

Consider renaming to DeleteChannelById to accurately reflect its behavior and avoid confusion.

Proposed rename
-func DeleteChannelByStatusAndId(channelId int) error {
+func DeleteChannelById(channelId int) error {
 	var channel Channel
 	if err := DB.First(&channel, channelId).Error; err != nil {
 		return err
 	}
 	return channel.Delete()
 }

Also update the call site in service/channel.go line 104:

-	err := model.DeleteChannelByStatusAndId(channelError.ChannelId)
+	err := model.DeleteChannelById(channelError.ChannelId)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
func DeleteChannelByStatusAndId(channelId int) error {
var channel Channel
if err := DB.First(&channel, channelId).Error; err != nil {
return err
}
return channel.Delete()
}
func DeleteChannelById(channelId int) error {
var channel Channel
if err := DB.First(&channel, channelId).Error; err != nil {
return err
}
return channel.Delete()
}
🤖 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 `@model/channel.go` around lines 875 - 881, Rename the misleading function
DeleteChannelByStatusAndId to DeleteChannelById and update its signature/usage
accordingly: keep the implementation that loads a Channel by ID and calls
channel.Delete(), and remove any expectation of a status parameter (the
status-based logic remains in DeleteChannelByStatus); then find and update all
call sites that reference DeleteChannelByStatusAndId (e.g., in the channel
service layer) to call DeleteChannelById instead so names accurately reflect
behavior.

@seefs001 seefs001 closed this May 29, 2026
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.

2 participants