@@ -27,6 +27,14 @@ import (
27
27
var (
28
28
// ErrTimeout is returned when a script times out.
29
29
ErrTimeout = xerrors .New ("script timed out" )
30
+ // ErrOutputPipesOpen is returned when a script exits leaving the output
31
+ // pipe(s) (stdout, stderr) open. This happens because we set WaitDelay on
32
+ // the command, which gives us two things:
33
+ //
34
+ // 1. The ability to ensure that a script exits (this is important for e.g.
35
+ // blocking login, and avoiding doing so indefinitely)
36
+ // 2. Improved command cancellation on timeout
37
+ ErrOutputPipesOpen = xerrors .New ("script exited without closing output pipes" )
30
38
31
39
parser = cron .NewParser (cron .Second | cron .Minute | cron .Hour | cron .Dom | cron .Month | cron .DowOptional )
32
40
)
@@ -248,7 +256,22 @@ func (r *Runner) run(ctx context.Context, script codersdk.WorkspaceAgentScript)
248
256
err = cmdCtx .Err ()
249
257
case err = <- cmdDone :
250
258
}
251
- if errors .Is (err , context .DeadlineExceeded ) {
259
+ switch {
260
+ case errors .Is (err , exec .ErrWaitDelay ):
261
+ err = ErrOutputPipesOpen
262
+ message := fmt .Sprintf ("script exited successfully, but output pipes were not closed after %s" , cmd .WaitDelay )
263
+ details := fmt .Sprint (
264
+ "This usually means a child process was started with references to stdout or stderr. As a result, this " +
265
+ "process may now have been terminated. Consider redirecting the output or using a separate " +
266
+ "\" coder_script\" for the process, see " +
267
+ "https://coder.com/docs/v2/latest/templates/troubleshooting#startup-script-issues for more information." ,
268
+ )
269
+ // Inform the user by propagating the message via log writers.
270
+ _ , _ = fmt .Fprintf (cmd .Stderr , "WARNING: %s. %s\n " , message , details )
271
+ // Also log to agent logs for ease of debugging.
272
+ r .Logger .Warn (ctx , message , slog .F ("details" , details ), slog .Error (err ))
273
+
274
+ case errors .Is (err , context .DeadlineExceeded ):
252
275
err = ErrTimeout
253
276
}
254
277
return err
0 commit comments