From 318aae18d55150cc71c35767a0164fb72b87c20d Mon Sep 17 00:00:00 2001 From: Mike Sawka Date: Thu, 14 Mar 2024 23:58:09 -0700 Subject: [PATCH] better exit code handling -- fix error highlights to not cover SIGINT or SIGPIPE (#465) * fix exitcode return to handle signals correctly -- use bash convention of 128 + signum. don't show red error mask for SIGINT or SIGPIPE * dont show left border for errors unless selected --- public/themes/default.css | 1 - src/app/line/line.less | 1 - src/app/line/linecomps.tsx | 14 +++++++++--- waveshell/pkg/packet/combined.go | 37 -------------------------------- waveshell/pkg/shexec/shexec.go | 21 ++++++++++++++++-- 5 files changed, 30 insertions(+), 44 deletions(-) delete mode 100644 waveshell/pkg/packet/combined.go diff --git a/public/themes/default.css b/public/themes/default.css index 33c1af4aa..731ca04de 100644 --- a/public/themes/default.css +++ b/public/themes/default.css @@ -156,7 +156,6 @@ --line-text-color: rgb(211, 215, 207); --line-svg-fill-color: rgb(150, 152, 150); --line-svg-hover-fill-color: #eceeec; - --line-selected-border-color: rgb(193, 195, 193); --line-separator-color: rgb(126, 126, 126); --line-error-color: var(--app-error-color); --line-warning-color: var(--app-warning-color); diff --git a/src/app/line/line.less b/src/app/line/line.less index 5022dc591..532ac3490 100644 --- a/src/app/line/line.less +++ b/src/app/line/line.less @@ -69,7 +69,6 @@ &.error-mask { background-color: var(--line-error-bg-color); - border-left: 4px solid var(--line-error-border-left-color); } } diff --git a/src/app/line/linecomps.tsx b/src/app/line/linecomps.tsx index 56b6893eb..88666b6b5 100644 --- a/src/app/line/linecomps.tsx +++ b/src/app/line/linecomps.tsx @@ -53,8 +53,16 @@ let heightLog = {}; dayjs.extend(localizedFormat); -function cmdHasError(cmd: Cmd): boolean { - return cmd.getStatus() == "error" || cmd.getExitCode() != 0; +function cmdShouldMarkError(cmd: Cmd): boolean { + if (cmd.getStatus() == "error") { + return true; + } + let exitCode = cmd.getExitCode(); + // 0, SIGINT, or SIGPIPE + if (exitCode == 0 || exitCode == 130 || exitCode == 141) { + return false; + } + return true; } function getIsHidePrompt(line: LineType): boolean { @@ -701,7 +709,7 @@ class LineCmd extends React.Component< ) .get(); const isRunning = cmd.isRunning(); - const cmdError = cmdHasError(cmd); + const cmdError = cmdShouldMarkError(cmd); const mainDivCn = cn( "line", "line-cmd", diff --git a/waveshell/pkg/packet/combined.go b/waveshell/pkg/packet/combined.go deleted file mode 100644 index 76ce09480..000000000 --- a/waveshell/pkg/packet/combined.go +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2023, Command Line Inc. -// SPDX-License-Identifier: Apache-2.0 - -package packet - -type CombinedPacket struct { - Type string `json:"type"` - Success bool `json:"success"` - Ts int64 `json:"ts"` - Id string `json:"id,omitempty"` - - SessionId string `json:"sessionid"` - CmdId string `json:"cmdid"` - - PtyPos int64 `json:"ptypos"` - PtyLen int64 `json:"ptylen"` - RunPos int64 `json:"runpos"` - RunLen int64 `json:"runlen"` - - Error string `json:"error"` - NotFound bool `json:"notfound,omitempty"` - Tail bool `json:"tail,omitempty"` - Dir string `json:"dir"` - ChDir string `json:"chdir,omitempty"` - - Data string `json:"data"` - PtyData string `json:"ptydata"` - RunData string `json:"rundata"` - Message string `json:"message"` - Command string `json:"command"` - - ScHomeDir string `json:"schomedir"` - HomeDir string `json:"homedir"` - Env []string `json:"env"` - ExitCode int `json:"exitcode"` - RunnerPid int `json:"runnerpid"` -} diff --git a/waveshell/pkg/shexec/shexec.go b/waveshell/pkg/shexec/shexec.go index 817692bbe..72a291a14 100644 --- a/waveshell/pkg/shexec/shexec.go +++ b/waveshell/pkg/shexec/shexec.go @@ -1069,6 +1069,23 @@ func copyToCirFile(dest *cirfile.File, src io.Reader) error { } } +func GetCmdExitCode(cmd *exec.Cmd, err error) int { + if cmd == nil || cmd.ProcessState == nil { + return GetExitCode(err) + } + status, ok := cmd.ProcessState.Sys().(syscall.WaitStatus) + if !ok { + return cmd.ProcessState.ExitCode() + } + signaled := status.Signaled() + if signaled { + signal := status.Signal() + return 128 + int(signal) + } + exitStatus := status.ExitStatus() + return exitStatus +} + func GetExitCode(err error) int { if err == nil { return 0 @@ -1082,7 +1099,6 @@ func GetExitCode(err error) int { func (c *ShExecType) ProcWait() error { exitErr := c.Cmd.Wait() - base.Logf("procwait: %v\n", exitErr) c.Lock.Lock() c.Exited = true c.Lock.Unlock() @@ -1095,6 +1111,7 @@ func (c *ShExecType) IsExited() bool { return c.Exited } +// called in waveshell --single mode (returns the real cmddone packet) func (c *ShExecType) WaitForCommand() *packet.CmdDonePacketType { donePacket := packet.MakeCmdDonePacket(c.CK) exitErr := c.ProcWait() @@ -1116,7 +1133,7 @@ func (c *ShExecType) WaitForCommand() *packet.CmdDonePacketType { endTs := time.Now() cmdDuration := endTs.Sub(c.StartTs) donePacket.Ts = endTs.UnixMilli() - donePacket.ExitCode = GetExitCode(exitErr) + donePacket.ExitCode = GetCmdExitCode(c.Cmd, exitErr) donePacket.DurationMs = int64(cmdDuration / time.Millisecond) if c.FileNames != nil { os.Remove(c.FileNames.StdinFifo) // best effort (no need to check error)