diff --git a/internal/shell/shell.go b/internal/shell/shell.go index d8dde82a0077d3be5cd19c2714e5a1a5097d015c..580ab3c5d592f6e2f41bbf65dfea6990d3b35b2f 100644 --- a/internal/shell/shell.go +++ b/internal/shell/shell.go @@ -259,20 +259,29 @@ func (s *Shell) updateShellFromRunner(runner *interp.Runner) { } // execCommon is the shared implementation for executing commands -func (s *Shell) execCommon(ctx context.Context, command string, stdout, stderr io.Writer) error { +func (s *Shell) execCommon(ctx context.Context, command string, stdout, stderr io.Writer) (err error) { + var runner *interp.Runner + defer func() { + if r := recover(); r != nil { + err = fmt.Errorf("command execution panic: %v", r) + } + if runner != nil { + s.updateShellFromRunner(runner) + } + s.logger.InfoPersist("command finished", "command", command, "err", err) + }() + line, err := syntax.NewParser().Parse(strings.NewReader(command), "") if err != nil { return fmt.Errorf("could not parse command: %w", err) } - runner, err := s.newInterp(stdout, stderr) + runner, err = s.newInterp(stdout, stderr) if err != nil { return fmt.Errorf("could not run command: %w", err) } err = runner.Run(ctx, line) - s.updateShellFromRunner(runner) - s.logger.InfoPersist("command finished", "command", command, "err", err) return err }