From c0fd8d3818f2132fcb050edb0031523749b469b9 Mon Sep 17 00:00:00 2001 From: Deivid Soto Date: Mon, 30 Mar 2026 23:34:36 +0200 Subject: [PATCH] fix(lint): exclude common fire-and-forget patterns from errcheck --- .golangci.yml | 16 +++++++++++++++- internal/agent/transport_ws.go | 2 +- internal/arr/discover_e2e_test.go | 2 +- internal/config/config.go | 2 +- internal/config/config_test.go | 4 ++-- internal/config/paths_test.go | 2 +- internal/library/mediainfo/ffprobe_download.go | 5 ++--- internal/mediaserver/detect.go | 4 ++-- 8 files changed, 25 insertions(+), 12 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index d5c6099..3558b46 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -29,7 +29,21 @@ linters: - G104 # Allow unhandled errors in fire-and-forget (notifications) errcheck: exclude-functions: - - (*os/exec.Cmd).Start # Fire-and-forget for notifications + - (*os/exec.Cmd).Start # Fire-and-forget for notifications + - (*os.File).Close # Deferred close — error irrelevant after read + - (io.Closer).Close # Same pattern for interfaces + - (*compress/gzip.Reader).Close + - (*archive/tar.Reader).Close + - (net.Conn).Close # Best-effort cleanup + - os.Remove # Best-effort cleanup of temp files + - os.RemoveAll + - os.Unsetenv # Test-only, always succeeds + - fmt.Fprintf # Terminal output — error never actionable + - fmt.Printf + - fmt.Println + - (*github.com/fatih/color.Color).Fprintf + - (*github.com/fatih/color.Color).Printf + - (*github.com/fatih/color.Color).Println exhaustive: default-signifies-exhaustive: true misspell: diff --git a/internal/agent/transport_ws.go b/internal/agent/transport_ws.go index 8d2f956..4f87acf 100644 --- a/internal/agent/transport_ws.go +++ b/internal/agent/transport_ws.go @@ -69,7 +69,7 @@ func (t *WSTransport) Connect(ctx context.Context) error { conn, wsResp, err := dialer.DialContext(ctx, wsURLWithKey, header) if wsResp != nil && wsResp.Body != nil { - defer wsResp.Body.Close() //nolint:errcheck + defer wsResp.Body.Close() } if err != nil { return fmt.Errorf("ws dial: %w", err) diff --git a/internal/arr/discover_e2e_test.go b/internal/arr/discover_e2e_test.go index 0245ae2..6a0a07a 100644 --- a/internal/arr/discover_e2e_test.go +++ b/internal/arr/discover_e2e_test.go @@ -21,7 +21,7 @@ func TestDiscoverE2E(t *testing.T) { if err != nil { t.Skipf("Port %s not reachable, skipping", port) } - _ = conn.Close() + conn.Close() } t.Run("Discover", func(t *testing.T) { diff --git a/internal/config/config.go b/internal/config/config.go index c4948ef..04195b7 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -171,7 +171,7 @@ func Save(cfg Config, path string) error { } if err := os.Rename(tmpPath, path); err != nil { - _ = os.Remove(tmpPath) + os.Remove(tmpPath) return fmt.Errorf("rename config: %w", err) } diff --git a/internal/config/config_test.go b/internal/config/config_test.go index e9746e4..3190399 100644 --- a/internal/config/config_test.go +++ b/internal/config/config_test.go @@ -93,7 +93,7 @@ func TestLoadPreservesDefaults(t *testing.T) { path := filepath.Join(tmp, "config.toml") // Write partial config (only auth section) - _ = os.WriteFile(path, []byte(`[auth] + os.WriteFile(path, []byte(`[auth] api_key = "tc_partial" `), 0o644) @@ -193,7 +193,7 @@ func TestParseSpeed(t *testing.T) { func TestLoadInvalidTOML(t *testing.T) { tmp := t.TempDir() path := filepath.Join(tmp, "config.toml") - _ = os.WriteFile(path, []byte(`not valid toml [[[`), 0o644) + os.WriteFile(path, []byte(`not valid toml [[[`), 0o644) _, err := Load(path) if err == nil { diff --git a/internal/config/paths_test.go b/internal/config/paths_test.go index e3fdb33..ed93044 100644 --- a/internal/config/paths_test.go +++ b/internal/config/paths_test.go @@ -43,7 +43,7 @@ func TestDirOverrideEnv(t *testing.T) { func TestDirXDGOverride(t *testing.T) { // Clear the custom env so XDG takes effect - _ = os.Unsetenv("UNARR_CONFIG_DIR") + os.Unsetenv("UNARR_CONFIG_DIR") t.Setenv("XDG_CONFIG_HOME", "/xdg/config") dir := Dir() diff --git a/internal/library/mediainfo/ffprobe_download.go b/internal/library/mediainfo/ffprobe_download.go index 0e4a739..ad7aeb6 100644 --- a/internal/library/mediainfo/ffprobe_download.go +++ b/internal/library/mediainfo/ffprobe_download.go @@ -97,8 +97,7 @@ func DownloadFFprobe() (string, error) { if err != nil { return "", fmt.Errorf("download failed: %w", err) } - defer resp.Body.Close() //nolint:errcheck // best-effort close - + defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return "", fmt.Errorf("download failed: HTTP %d", resp.StatusCode) } @@ -167,7 +166,7 @@ func extractFromZip(data []byte, target string) ([]byte, error) { if err != nil { return nil, fmt.Errorf("cannot extract %s from archive: %w", target, err) } - defer rc.Close() //nolint:errcheck // best-effort close + defer rc.Close() return io.ReadAll(rc) } } diff --git a/internal/mediaserver/detect.go b/internal/mediaserver/detect.go index 0680519..e0b3030 100644 --- a/internal/mediaserver/detect.go +++ b/internal/mediaserver/detect.go @@ -113,7 +113,7 @@ func plexLibraryPaths() []string { if err != nil { return nil } - defer resp.Body.Close() //nolint:errcheck // best-effort close + defer resp.Body.Close() if resp.StatusCode != 200 { return nil @@ -200,7 +200,7 @@ func jellyfinLibraryPaths(baseURL string) []string { if err != nil { return nil } - defer resp.Body.Close() //nolint:errcheck // best-effort close + defer resp.Body.Close() if resp.StatusCode != 200 { return nil