noctx は context.Context を渡さずに呼び出している関数を検出するツールです。
解決する問題 http.Get などの context を受け取らない関数を使うと、リクエストのキャンセルやタイムアウト制御ができません。長時間応答しない外部 API に対してリクエストが滞留し、goroutine リークやリソース枯渇を引き起こします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 func FetchUser (url string ) (*User, error ) { resp, err := http.Get(url) if err != nil { return nil , fmt.Errorf("fetch user: %w" , err) } defer resp.Body.Close() var user User if err := json.NewDecoder(resp.Body).Decode(&user); err != nil { return nil , fmt.Errorf("decode user: %w" , err) } return &user, nil }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 func FetchUser (ctx context.Context, url string ) (*User, error ) { req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil ) if err != nil { return nil , fmt.Errorf("create request: %w" , err) } resp, err := http.DefaultClient.Do(req) if err != nil { return nil , fmt.Errorf("fetch user: %w" , err) } defer func () { if err := resp.Body.Close(); err != nil { slog.Error("close response body" , "error" , err) } }() var user User if err := json.NewDecoder(resp.Body).Decode(&user); err != nil { return nil , fmt.Errorf("decode user: %w" , err) } return &user, nil }
設定 公式ドキュメント
設定オプションはありません。有効化するだけで動作します。
1 2 3 4 5 6 version: "2" linters: enable: - noctx
オプション golangci-lint 経由では設定オプションはありません。
サンプル 検出例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 func example () { resp, _ := http.Get("https://example.com" ) resp, _ = http.Head("https://example.com" ) resp, _ = http.Post("https://example.com" , "" , nil ) resp, _ = http.PostForm("https://example.com" , nil ) _ = resp req, _ := http.NewRequest("GET" , "https://example.com" , nil ) _ = req }
修正例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 func example (ctx context.Context) error { req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://example.com" , nil ) if err != nil { return fmt.Errorf("create request: %w" , err) } resp, err := http.DefaultClient.Do(req) if err != nil { return fmt.Errorf("do request: %w" , err) } defer func () { if err := resp.Body.Close(); err != nil { slog.Error("close response body" , "error" , err) } }() return nil }
注意点
http.Get / http.Post などの便利関数は常に http.NewRequestWithContext + Client.Do に置き換える
http.NewRequest も検出対象。http.NewRequestWithContext を使う
noctx は net/http 以外にも database/sql、net、os/exec パッケージの context なし呼び出しも検出する
参考リンク