Skip to content

Commit 05d9aa1

Browse files
authored
Merge pull request #1699 from dgageot/fix-issues
Fix issues found by the review agent
2 parents 859a975 + e49232f commit 05d9aa1

File tree

5 files changed

+39
-19
lines changed

5 files changed

+39
-19
lines changed

cmd/root/api.go

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,26 @@ func newAPICmd() *cobra.Command {
5656

5757
// monitorStdin monitors stdin for EOF, which indicates the parent process has died.
5858
// When spawned with piped stdio, stdin closes when the parent process dies.
59+
// The caller is responsible for cancelling the context (e.g. via defer cancel()).
5960
func monitorStdin(ctx context.Context, cancel context.CancelFunc, stdin *os.File) {
60-
// Close stdin when context is cancelled to unblock the read
61+
done := make(chan struct{})
62+
63+
// Close stdin when context is cancelled to unblock the read.
64+
// Also exits cleanly when monitorStdin returns.
6165
go func() {
62-
<-ctx.Done()
66+
select {
67+
case <-ctx.Done():
68+
case <-done:
69+
}
6370
stdin.Close()
6471
}()
6572

73+
defer close(done)
74+
6675
buf := make([]byte, 1)
6776
for {
6877
n, err := stdin.Read(buf)
6978
if err != nil || n == 0 {
70-
// Only log and cancel if context isn't already done (parent died)
7179
if ctx.Err() == nil {
7280
slog.Info("stdin closed, parent process likely died, shutting down")
7381
cancel()
@@ -113,10 +121,14 @@ func (f *apiFlags) runAPICommand(cmd *cobra.Command, args []string) error {
113121
}()
114122

115123
// Start recording proxy if --record is specified
116-
if _, cleanup, err := setupRecordingProxy(f.recordPath, &f.runConfig); err != nil {
124+
if _, recordCleanup, err := setupRecordingProxy(f.recordPath, &f.runConfig); err != nil {
117125
return err
118-
} else if cleanup != nil {
119-
defer cleanup()
126+
} else if recordCleanup != nil {
127+
defer func() {
128+
if err := recordCleanup(); err != nil {
129+
slog.Error("Failed to cleanup recording proxy", "error", err)
130+
}
131+
}()
120132
}
121133

122134
if f.pullIntervalMins > 0 && !config.IsOCIReference(agentsPath) {

cmd/root/record.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ func setupFakeProxy(fakeResponses string, streamDelayMs int, runConfig *config.R
4545
// and normalizes the path by stripping any .yaml suffix.
4646
// Returns the cassette path (with .yaml extension) and a cleanup function.
4747
// The cleanup function must be called when done (typically via defer).
48-
func setupRecordingProxy(recordPath string, runConfig *config.RuntimeConfig) (cassettePath string, cleanup func(), err error) {
48+
func setupRecordingProxy(recordPath string, runConfig *config.RuntimeConfig) (cassettePath string, cleanup func() error, err error) {
4949
if recordPath == "" {
50-
return "", func() {}, nil
50+
return "", func() error { return nil }, nil
5151
}
5252

5353
// Handle auto-generated filename (from NoOptDefVal)
@@ -67,9 +67,5 @@ func setupRecordingProxy(recordPath string, runConfig *config.RuntimeConfig) (ca
6767

6868
slog.Info("Recording mode enabled", "cassette", cassettePath, "proxy", proxyURL)
6969

70-
return cassettePath, func() {
71-
if err := cleanupFn(); err != nil {
72-
slog.Error("Failed to cleanup recording proxy", "error", err)
73-
}
74-
}, nil
70+
return cassettePath, cleanupFn, nil
7571
}

cmd/root/record_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ func TestSetupRecordingProxy_EmptyPath(t *testing.T) {
2121
assert.NotNil(t, cleanup)
2222
assert.Empty(t, runConfig.ModelsGateway, "ModelsGateway should not be set")
2323

24-
cleanup()
24+
require.NoError(t, cleanup())
2525
}
2626

2727
func TestSetupRecordingProxy_AutoGeneratesFilename(t *testing.T) {
@@ -31,7 +31,7 @@ func TestSetupRecordingProxy_AutoGeneratesFilename(t *testing.T) {
3131

3232
cassettePath, cleanup, err := setupRecordingProxy("true", &runConfig)
3333
require.NoError(t, err)
34-
defer cleanup()
34+
defer func() { require.NoError(t, cleanup()) }()
3535

3636
assert.True(t, strings.HasPrefix(cassettePath, "cagent-recording-"), "should have auto-generated prefix")
3737
assert.True(t, strings.HasSuffix(cassettePath, ".yaml"), "should have .yaml suffix")
@@ -46,7 +46,7 @@ func TestSetupRecordingProxy_CreatesProxy(t *testing.T) {
4646

4747
resultPath, cleanup, err := setupRecordingProxy(cassettePath, &runConfig)
4848
require.NoError(t, err)
49-
defer cleanup()
49+
defer func() { require.NoError(t, cleanup()) }()
5050

5151
assert.Equal(t, cassettePath+".yaml", resultPath)
5252
assert.True(t, strings.HasPrefix(runConfig.ModelsGateway, "http://"), "ModelsGateway should be HTTP URL")

cmd/root/root.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ func NewRootCmd() *cobra.Command {
6565
},
6666
PersistentPostRunE: func(cmd *cobra.Command, args []string) error {
6767
if flags.logFile != nil {
68-
_ = flags.logFile.Close()
68+
if err := flags.logFile.Close(); err != nil {
69+
slog.Error("Failed to close log file", "error", err)
70+
}
6971
}
7072
return nil
7173
},

cmd/root/run.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ func (f *runExecFlags) runRunCommand(cmd *cobra.Command, args []string) error {
119119
return f.runOrExec(ctx, out, args, tui)
120120
}
121121

122-
func (f *runExecFlags) runOrExec(ctx context.Context, out *cli.Printer, args []string, tui bool) error {
122+
func (f *runExecFlags) runOrExec(ctx context.Context, out *cli.Printer, args []string, tui bool) (retErr error) {
123123
slog.Debug("Starting agent", "agent", f.agentName)
124124

125125
// Start CPU profiling if requested
@@ -193,6 +193,9 @@ func (f *runExecFlags) runOrExec(ctx context.Context, out *cli.Printer, args []s
193193
defer func() {
194194
if err := fakeCleanup(); err != nil {
195195
slog.Error("Failed to cleanup fake proxy", "error", err)
196+
if retErr == nil {
197+
retErr = fmt.Errorf("failed to cleanup fake proxy: %w", err)
198+
}
196199
}
197200
}()
198201

@@ -202,7 +205,14 @@ func (f *runExecFlags) runOrExec(ctx context.Context, out *cli.Printer, args []s
202205
return err
203206
}
204207
if cassettePath != "" {
205-
defer recordCleanup()
208+
defer func() {
209+
if err := recordCleanup(); err != nil {
210+
slog.Error("Failed to cleanup recording proxy", "error", err)
211+
if retErr == nil {
212+
retErr = fmt.Errorf("failed to cleanup recording proxy: %w", err)
213+
}
214+
}
215+
}()
206216
out.Println("Recording mode enabled, cassette: " + cassettePath)
207217
}
208218

0 commit comments

Comments
 (0)