feat: 配置 golangci-lint 静态分析并修复存量违规
- 新增 backend/.golangci.yml 配置 12 个 linter(forbidigo、errorlint、errcheck、staticcheck、revive、gocritic、gosec、bodyclose、noctx、nilerr、goimports、gocyclo) - 新增 lefthook.yml 配置 pre-commit hook 自动运行 lint - 修复存量代码违规:errors.Is/As 替换、zap.Error 替换、import 排序、errcheck 修复 - 更新 README 补充编码规范说明 - 归档 backend-code-lint 变更
This commit is contained in:
@@ -51,6 +51,7 @@ type Client struct {
|
||||
}
|
||||
|
||||
// ProviderClient 供应商客户端接口
|
||||
//
|
||||
//go:generate go run go.uber.org/mock/mockgen -source=client.go -destination=../../tests/mocks/mock_provider_client.go -package=mocks
|
||||
type ProviderClient interface {
|
||||
Send(ctx context.Context, spec conversion.HTTPRequestSpec) (*conversion.HTTPResponseSpec, error)
|
||||
@@ -141,7 +142,10 @@ func (c *Client) SendStream(ctx context.Context, spec conversion.HTTPRequestSpec
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
defer resp.Body.Close()
|
||||
cancel()
|
||||
errBody, _ := io.ReadAll(resp.Body)
|
||||
errBody, readErr := io.ReadAll(resp.Body)
|
||||
if readErr != nil {
|
||||
return nil, fmt.Errorf("供应商返回错误: HTTP %d,读取错误响应失败: %w", resp.StatusCode, readErr)
|
||||
}
|
||||
if len(errBody) > 0 {
|
||||
return nil, fmt.Errorf("供应商返回错误: HTTP %d: %s", resp.StatusCode, string(errBody))
|
||||
}
|
||||
@@ -184,7 +188,7 @@ func (c *Client) readStream(ctx context.Context, cancel context.CancelFunc, body
|
||||
if err != nil {
|
||||
if err != io.EOF {
|
||||
if isNetworkError(err) {
|
||||
c.logger.Error("流网络错误", zap.String("error", err.Error()))
|
||||
c.logger.Error("流网络错误", zap.Error(err))
|
||||
eventChan <- StreamEvent{Error: fmt.Errorf("网络错误: %w", err)}
|
||||
} else {
|
||||
c.logger.Error("流读取错误", zap.Error(err))
|
||||
|
||||
@@ -41,7 +41,8 @@ func TestClient_Send_Success(t *testing.T) {
|
||||
assert.Equal(t, "Bearer test-key", r.Header.Get("Authorization"))
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{"id":"test","model":"gpt-4"}`))
|
||||
_, err := w.Write([]byte(`{"id":"test","model":"gpt-4"}`))
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
@@ -65,7 +66,8 @@ func TestClient_Send_Success(t *testing.T) {
|
||||
func TestClient_Send_ErrorResponse(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.Write([]byte(`{"error":{"message":"Invalid API key"}}`))
|
||||
_, err := w.Write([]byte(`{"error":{"message":"Invalid API key"}}`))
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
@@ -140,12 +142,15 @@ func TestClient_SendStream_SSEEvents(t *testing.T) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
flusher, ok := w.(http.Flusher)
|
||||
require.True(t, ok)
|
||||
w.Write([]byte("data: {\"id\":\"1\",\"choices\":[{\"delta\":{\"content\":\"Hello\"}}]}\n\n"))
|
||||
_, err := w.Write([]byte("data: {\"id\":\"1\",\"choices\":[{\"delta\":{\"content\":\"Hello\"}}]}\n\n"))
|
||||
require.NoError(t, err)
|
||||
flusher.Flush()
|
||||
w.Write([]byte("data: {\"id\":\"1\",\"choices\":[{\"delta\":{\"content\":\" World\"}}]}\n\n"))
|
||||
_, err = w.Write([]byte("data: {\"id\":\"1\",\"choices\":[{\"delta\":{\"content\":\" World\"}}]}\n\n"))
|
||||
require.NoError(t, err)
|
||||
flusher.Flush()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
w.Write([]byte("data: [DONE]\n\n"))
|
||||
_, err = w.Write([]byte("data: [DONE]\n\n"))
|
||||
require.NoError(t, err)
|
||||
flusher.Flush()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}))
|
||||
@@ -165,11 +170,12 @@ func TestClient_SendStream_SSEEvents(t *testing.T) {
|
||||
var dataEvents [][]byte
|
||||
var doneEvents int
|
||||
for event := range eventChan {
|
||||
if event.Done {
|
||||
switch {
|
||||
case event.Done:
|
||||
doneEvents++
|
||||
} else if event.Error != nil {
|
||||
case event.Error != nil:
|
||||
t.Fatalf("unexpected error: %v", event.Error)
|
||||
} else {
|
||||
default:
|
||||
dataEvents = append(dataEvents, event.Data)
|
||||
}
|
||||
}
|
||||
@@ -215,7 +221,8 @@ func TestClient_Send_EmptyBody(t *testing.T) {
|
||||
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
assert.Equal(t, "GET", r.Method)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte(`{"result":"ok"}`))
|
||||
_, err := w.Write([]byte(`{"result":"ok"}`))
|
||||
require.NoError(t, err)
|
||||
}))
|
||||
defer server.Close()
|
||||
|
||||
@@ -238,10 +245,12 @@ func TestClient_SendStream_SlowSSE(t *testing.T) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
flusher, ok := w.(http.Flusher)
|
||||
require.True(t, ok)
|
||||
w.Write([]byte("data: {\"id\":\"1\"}\n\n"))
|
||||
_, err := w.Write([]byte("data: {\"id\":\"1\"}\n\n"))
|
||||
require.NoError(t, err)
|
||||
flusher.Flush()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
w.Write([]byte("data: [DONE]\n\n"))
|
||||
_, err = w.Write([]byte("data: [DONE]\n\n"))
|
||||
require.NoError(t, err)
|
||||
flusher.Flush()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}))
|
||||
@@ -261,11 +270,12 @@ func TestClient_SendStream_SlowSSE(t *testing.T) {
|
||||
var dataCount int
|
||||
var doneCount int
|
||||
for event := range eventChan {
|
||||
if event.Done {
|
||||
switch {
|
||||
case event.Done:
|
||||
doneCount++
|
||||
} else if event.Error != nil {
|
||||
case event.Error != nil:
|
||||
t.Fatalf("unexpected error: %v", event.Error)
|
||||
} else {
|
||||
default:
|
||||
dataCount++
|
||||
}
|
||||
}
|
||||
@@ -279,10 +289,12 @@ func TestClient_SendStream_SplitSSEEvents(t *testing.T) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
flusher, ok := w.(http.Flusher)
|
||||
require.True(t, ok)
|
||||
w.Write([]byte("data: {\"id\":\"1\"}\n\ndata: {\"id\":\"2\"}\n\n"))
|
||||
_, err := w.Write([]byte("data: {\"id\":\"1\"}\n\ndata: {\"id\":\"2\"}\n\n"))
|
||||
require.NoError(t, err)
|
||||
flusher.Flush()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
w.Write([]byte("data: [DONE]\n\n"))
|
||||
_, err = w.Write([]byte("data: [DONE]\n\n"))
|
||||
require.NoError(t, err)
|
||||
flusher.Flush()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}))
|
||||
@@ -364,13 +376,14 @@ func TestClient_SendStream_MidStreamNetworkError(t *testing.T) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
flusher, ok := w.(http.Flusher)
|
||||
require.True(t, ok)
|
||||
w.Write([]byte("data: {\"id\":\"1\"}\n\n"))
|
||||
_, err := w.Write([]byte("data: {\"id\":\"1\"}\n\n"))
|
||||
require.NoError(t, err)
|
||||
flusher.Flush()
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
if hijacker, ok := w.(http.Hijacker); ok {
|
||||
conn, _, _ := hijacker.Hijack()
|
||||
if conn != nil {
|
||||
conn.Close()
|
||||
require.NoError(t, conn.Close())
|
||||
}
|
||||
}
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user