Skip to content

Commit 003e23b

Browse files
fix: add HTTP timeouts and handle ignored errors
Add 15s timeout to FetchRemoteConfig and 30s timeout to snapshot upload/import HTTP clients. Fix ignored io.ReadAll error and unhandled exec.Command("open") error in snapshot upload. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
1 parent 36d61b4 commit 003e23b

2 files changed

Lines changed: 18 additions & 5 deletions

File tree

internal/cli/snapshot.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"os/exec"
1111
"path/filepath"
1212
"strings"
13+
"time"
1314

1415
"github.com/charmbracelet/lipgloss"
1516
"github.com/openbootdotdev/openboot/internal/auth"
@@ -226,14 +227,18 @@ func uploadSnapshot(snap *snapshot.Snapshot) error {
226227
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", stored.Token))
227228
req.Header.Set("Content-Type", "application/json")
228229

229-
resp, err := http.DefaultClient.Do(req)
230+
uploadClient := &http.Client{Timeout: 30 * time.Second}
231+
resp, err := uploadClient.Do(req)
230232
if err != nil {
231233
return fmt.Errorf("failed to upload snapshot: %w", err)
232234
}
233235
defer resp.Body.Close()
234236

235237
if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated {
236-
respBody, _ := io.ReadAll(resp.Body)
238+
respBody, err := io.ReadAll(resp.Body)
239+
if err != nil {
240+
return fmt.Errorf("upload failed (status %d): failed to read response: %w", resp.StatusCode, err)
241+
}
237242
return fmt.Errorf("upload failed (status %d): %s", resp.StatusCode, string(respBody))
238243
}
239244

@@ -259,7 +264,9 @@ func uploadSnapshot(snap *snapshot.Snapshot) error {
259264
fmt.Fprintln(os.Stderr)
260265

261266
// Auto-open browser
262-
exec.Command("open", configURL).Start()
267+
if err := exec.Command("open", configURL).Start(); err != nil {
268+
ui.Warn(fmt.Sprintf("Could not open browser: %v", err))
269+
}
263270
fmt.Fprintln(os.Stderr, snapMutedStyle.Render(" Opening in browser..."))
264271
fmt.Fprintln(os.Stderr)
265272

@@ -324,7 +331,8 @@ func runSnapshotImport(importPath string, dryRun bool) error {
324331
localPath := importPath
325332
if strings.HasPrefix(importPath, "http://") || strings.HasPrefix(importPath, "https://") {
326333
fmt.Fprintf(os.Stderr, " Downloading snapshot from %s...\n", importPath)
327-
resp, err := http.Get(importPath)
334+
client := &http.Client{Timeout: 30 * time.Second}
335+
resp, err := client.Get(importPath)
328336
if err != nil {
329337
return fmt.Errorf("failed to download snapshot: %w", err)
330338
}

internal/config/config.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,15 @@ import (
77
"log"
88
"net/http"
99
"strings"
10+
"time"
1011

1112
"gopkg.in/yaml.v3"
1213
)
1314

15+
var remoteHTTPClient = &http.Client{
16+
Timeout: 15 * time.Second,
17+
}
18+
1419
//go:embed data/presets.yaml
1520
var presetsYAML embed.FS
1621

@@ -95,7 +100,7 @@ func FetchRemoteConfig(userSlug string) (*RemoteConfig, error) {
95100

96101
url := fmt.Sprintf("https://openboot.dev/%s/%s/config", username, slug)
97102

98-
resp, err := http.Get(url)
103+
resp, err := remoteHTTPClient.Get(url)
99104
if err != nil {
100105
return nil, fmt.Errorf("failed to fetch config: %w", err)
101106
}

0 commit comments

Comments
 (0)