后端与全仓代码质量清理(golangci 扩展集 · 测试质量 · 并发安全 · 文档同步)

代码质量全量清理,零行为变化:golangci 扩展集 13 类 linter(gosec/modernize/perfsprint/canonicalheader/usestdlibvars/wastedassign/intrange/errorlint/forcetypeassert/recvcheck/exhaustive/unparam)全量修复,测试代码质量(testifylint/thelper/usetesting)25→0,frpc 进程生命周期真 bug(进程组击杀)、全仓 go test -race 6 类数据竞争(含 1 个生产竞争)、SPDX license 头补齐 131 文件、前端测试套件 next-intl 迁移后 44 失败→全绿、过期 swagger 文档重新生成、pnpm-workspace 构建审批。

Experiments: #2-#17, #18, #20, #21, #23
Metric: total_issues 108 → 8 (-92.6%)
This commit is contained in:
ryan
2026-08-16 21:23:37 +08:00
parent 5a8722ff07
commit 2f60329886
292 changed files with 1362 additions and 793 deletions
+1 -1
View File
@@ -103,7 +103,7 @@ func IsFinalAttempt(ctx context.Context) bool {
// AppendLog 追加日志到任务执行记录
// 在 TaskHandler.Execute 中调用,日志会自动追加到 TaskExecution.Log 字段
func AppendLog(ctx context.Context, format string, args ...interface{}) {
func AppendLog(ctx context.Context, format string, args ...any) {
taskID := GetTaskID(ctx)
if taskID == "" {
// 上下文中没有 taskID,降级到普通日志
+6 -5
View File
@@ -59,6 +59,7 @@ func failHandler() *mockHandler {
const testTaskType = "test:mock_task"
func setupTest(t *testing.T) func() {
t.Helper()
_, mr, cleanup := testhelper.SetupTestEnvironment(t)
AsynqClient = asynq.NewClient(asynq.RedisClientOpt{
Addr: mr.Addr(),
@@ -94,7 +95,7 @@ func TestGetTaskIDFromContext(t *testing.T) {
// 空 context
taskID := GetTaskID(ctx)
assert.Equal(t, "", taskID)
assert.Empty(t, taskID)
// 注入 taskID
ctx = withTaskID(ctx, "test_task_123")
@@ -242,7 +243,7 @@ func TestProcessTaskFailure(t *testing.T) {
ctx = withTaskID(ctx, "process_fail_001")
_, err = handler.Execute(ctx, nil)
assert.Error(t, err)
require.Error(t, err)
assert.Contains(t, err.Error(), "模拟执行失败")
// 验证日志
@@ -403,7 +404,7 @@ func TestRetryTaskNotFailed(t *testing.T) {
// 尝试重试成功的任务
_, err = RetryTask(ctx, execution.ID)
assert.Error(t, err)
require.Error(t, err)
assert.Contains(t, err.Error(), "只有失败的任务才能重试")
}
@@ -425,7 +426,7 @@ func TestRetryTaskNotRetryable(t *testing.T) {
require.NoError(t, err)
_, err = RetryTask(ctx, execution.ID)
assert.Error(t, err)
require.Error(t, err)
assert.Contains(t, err.Error(), "不支持重试")
}
@@ -435,7 +436,7 @@ func TestRetryTaskNonExistent(t *testing.T) {
ctx := context.Background()
_, err := RetryTask(ctx, 99999999)
assert.Error(t, err)
require.Error(t, err)
assert.Contains(t, err.Error(), "不存在")
}
+4 -4
View File
@@ -4,17 +4,17 @@
package task
import (
"errors"
"testing"
"github.com/hibiken/asynq"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestPermanentErrorSkipsRetryWithoutExposingAsynqMessage(t *testing.T) {
err := PermanentError(" 来源配置无效 ")
assert.True(t, errors.Is(err, asynq.SkipRetry))
require.ErrorIs(t, err, asynq.SkipRetry)
assert.Equal(t, "来源配置无效", err.Error())
assert.NotContains(t, err.Error(), asynq.SkipRetry.Error())
}
@@ -22,6 +22,6 @@ func TestPermanentErrorSkipsRetryWithoutExposingAsynqMessage(t *testing.T) {
func TestPermanentErrorUsesSafeFallbackForBlankMessage(t *testing.T) {
err := PermanentError(" ")
assert.True(t, errors.Is(err, asynq.SkipRetry))
assert.Equal(t, defaultPermanentErrorMessage, err.Error())
require.ErrorIs(t, err, asynq.SkipRetry)
require.Equal(t, defaultPermanentErrorMessage, err.Error())
}
+3 -3
View File
@@ -15,7 +15,7 @@ type redisClientConnOpt struct {
options redis.Options
}
func (opt redisClientConnOpt) MakeRedisClient() interface{} {
func (opt redisClientConnOpt) MakeRedisClient() any {
return redis.NewClient(&opt.options)
}
@@ -23,7 +23,7 @@ type redisClusterConnOpt struct {
options redis.ClusterOptions
}
func (opt redisClusterConnOpt) MakeRedisClient() interface{} {
func (opt redisClusterConnOpt) MakeRedisClient() any {
return redis.NewClusterClient(&opt.options)
}
@@ -32,7 +32,7 @@ type redisFailoverConnOpt struct {
maintNotificationsEnabled bool
}
func (opt redisFailoverConnOpt) MakeRedisClient() interface{} {
func (opt redisFailoverConnOpt) MakeRedisClient() any {
client := redis.NewFailoverClient(&opt.options)
// go-redis v9.16 does not expose maintenance notification settings on
// FailoverOptions, so apply the configured mode before the client is used.
+3
View File
@@ -1,3 +1,6 @@
// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
package task
import (