Skip to content

Commit fcf0714

Browse files
BadRat-inclaude
andcommitted
fix(lint): check all error returns in test and production code
Fixed all unchecked error return values to pass errcheck linter: 1. internal/updater/updater_test.go: - Added error checks for json.NewEncoder().Encode() calls - Added error checks for json.NewDecoder().Decode() calls - Added error checks for http.Response usage before checking errors - Added error checks for w.Write() in test HTTP handlers 2. internal/updater/updater.go: - Added error handling for os.Rename() when restoring backup - Added error handling for os.Remove() when cleaning up backup - Both use warning messages for non-fatal failures 3. internal/installer/installer.go: - Added error handling for i.saveState() with warning message - Ensures state save failures don't block error reporting 4. internal/installer/installer_test.go: - Added error checks for os.Chdir() in both defer and main call - Uses proper error handling in defer function All changes maintain existing behavior while satisfying linter requirements. Tests pass: go test -v -race ./... ✅ Vet passes: go vet ./... ✅ 🤖 Generated with Claude Code Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent e12d1f6 commit fcf0714

4 files changed

Lines changed: 51 additions & 15 deletions

File tree

internal/installer/installer.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ func (i *Installer) RunStage(stageConfigPath string) error {
102102
// Save state even on failure for resume capability
103103
state.LastStage = stageConfigPath
104104
state.LastUpdate = time.Now()
105-
i.saveState(state)
105+
if saveErr := i.saveState(state); saveErr != nil {
106+
i.ui.Warning("Failed to save state: %v", saveErr)
107+
}
106108

107109
return fmt.Errorf("stage execution failed: %w", err)
108110
}

internal/installer/installer_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,8 +295,14 @@ path = "~/test"
295295

296296
// Change to temp dir so LoadVersionsLock finds the file
297297
origDir, _ := os.Getwd()
298-
defer os.Chdir(origDir)
299-
os.Chdir(tmpDir)
298+
defer func() {
299+
if err := os.Chdir(origDir); err != nil {
300+
t.Errorf("Failed to restore directory: %v", err)
301+
}
302+
}()
303+
if err := os.Chdir(tmpDir); err != nil {
304+
t.Fatalf("Failed to change to temp directory: %v", err)
305+
}
300306

301307
ui := &mockUI{}
302308
installer := NewInstaller(ui, false)

internal/updater/updater.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,18 @@ func (u *Updater) Update(release *ReleaseInfo) error {
176176
tempFile.Close()
177177
if err := os.Rename(tempFile.Name(), currentExe); err != nil {
178178
// Restore backup on failure
179-
os.Rename(backupPath, currentExe)
179+
if restoreErr := os.Rename(backupPath, currentExe); restoreErr != nil {
180+
// Log but don't fail - original error is more important
181+
fmt.Fprintf(os.Stderr, "Warning: failed to restore backup: %v\n", restoreErr)
182+
}
180183
return fmt.Errorf("failed to replace binary: %w", err)
181184
}
182185

183186
// Remove backup on success
184-
os.Remove(backupPath)
187+
if err := os.Remove(backupPath); err != nil {
188+
// Non-fatal: backup removal failure doesn't break update
189+
fmt.Fprintf(os.Stderr, "Warning: failed to remove backup: %v\n", err)
190+
}
185191

186192
return nil
187193
}

internal/updater/updater_test.go

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ func TestCheckForUpdate_NewerVersionAvailable(t *testing.T) {
6464
}
6565

6666
w.Header().Set("Content-Type", "application/json")
67-
json.NewEncoder(w).Encode(release)
67+
if err := json.NewEncoder(w).Encode(release); err != nil {
68+
t.Errorf("Failed to encode response: %v", err)
69+
}
6870
}))
6971
defer server.Close()
7072

@@ -109,7 +111,9 @@ func TestCheckForUpdate_AlreadyLatest(t *testing.T) {
109111
}
110112

111113
w.Header().Set("Content-Type", "application/json")
112-
json.NewEncoder(w).Encode(release)
114+
if err := json.NewEncoder(w).Encode(release); err != nil {
115+
t.Errorf("Failed to encode response: %v", err)
116+
}
113117
}))
114118
defer server.Close()
115119

@@ -131,7 +135,9 @@ func TestCheckForUpdate_SkipDraftRelease(t *testing.T) {
131135
}
132136

133137
w.Header().Set("Content-Type", "application/json")
134-
json.NewEncoder(w).Encode(release)
138+
if err := json.NewEncoder(w).Encode(release); err != nil {
139+
t.Errorf("Failed to encode response: %v", err)
140+
}
135141
}))
136142
defer server.Close()
137143

@@ -140,11 +146,16 @@ func TestCheckForUpdate_SkipDraftRelease(t *testing.T) {
140146

141147
// Manually test draft detection
142148
req, _ := http.NewRequest("GET", server.URL, nil)
143-
resp, _ := updater.httpClient.Do(req)
149+
resp, err := updater.httpClient.Do(req)
150+
if err != nil {
151+
t.Fatalf("Request failed: %v", err)
152+
}
144153
defer resp.Body.Close()
145154

146155
var release ReleaseInfo
147-
json.NewDecoder(resp.Body).Decode(&release)
156+
if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
157+
t.Fatalf("Failed to decode response: %v", err)
158+
}
148159

149160
if !release.Draft {
150161
t.Error("Expected draft=true")
@@ -160,19 +171,26 @@ func TestCheckForUpdate_SkipPrereleaseRelease(t *testing.T) {
160171
}
161172

162173
w.Header().Set("Content-Type", "application/json")
163-
json.NewEncoder(w).Encode(release)
174+
if err := json.NewEncoder(w).Encode(release); err != nil {
175+
t.Errorf("Failed to encode response: %v", err)
176+
}
164177
}))
165178
defer server.Close()
166179

167180
updater := NewUpdater("v0.4.0")
168181
updater.httpClient = server.Client()
169182

170183
req, _ := http.NewRequest("GET", server.URL, nil)
171-
resp, _ := updater.httpClient.Do(req)
184+
resp, err := updater.httpClient.Do(req)
185+
if err != nil {
186+
t.Fatalf("Request failed: %v", err)
187+
}
172188
defer resp.Body.Close()
173189

174190
var release ReleaseInfo
175-
json.NewDecoder(resp.Body).Decode(&release)
191+
if err := json.NewDecoder(resp.Body).Decode(&release); err != nil {
192+
t.Fatalf("Failed to decode response: %v", err)
193+
}
176194

177195
if !release.Prerelease {
178196
t.Error("Expected prerelease=true")
@@ -190,7 +208,9 @@ func TestUpdate_SuccessfulUpdate(t *testing.T) {
190208

191209
// Create mock server for download
192210
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
193-
w.Write([]byte("new version"))
211+
if _, err := w.Write([]byte("new version")); err != nil {
212+
t.Errorf("Failed to write response: %v", err)
213+
}
194214
}))
195215
defer server.Close()
196216

@@ -359,7 +379,9 @@ func TestVerifyChecksum_FileNotFound(t *testing.T) {
359379
func TestDownloadFile(t *testing.T) {
360380
// Create mock server
361381
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
362-
w.Write([]byte("downloaded content"))
382+
if _, err := w.Write([]byte("downloaded content")); err != nil {
383+
t.Errorf("Failed to write response: %v", err)
384+
}
363385
}))
364386
defer server.Close()
365387

0 commit comments

Comments
 (0)