-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
What version of Go are you using (go version)?
$ go version go version go1.17.6 linux/amd64
Does this issue reproduce with the latest release?
Yes.
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GO111MODULE="" GOARCH="amd64" GOBIN="" GOCACHE="/home/[REDACTED]/.cache/go-build" GOENV="/home/[REDACTED]/.config/go/env" GOEXE="" GOEXPERIMENT="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOINSECURE="" GOMODCACHE="/[REDACTED]/go/pkg/mod" GONOPROXY="[REDACTED],[REDACTED]/*,github.com/[REDACTED]/*" GONOSUMDB="[REDACTED],[REDACTED]/*,github.com/[REDACTED]/*" GOOS="linux" GOPATH="/opt/dev/go" GOPRIVATE="[REDACTED],[REDACTED]/*,github.com/[REDACTED]/*" GOPROXY="https://proxy.golang.org,direct" GOROOT="/usr/lib/go" GOSUMDB="sum.golang.org" GOTMPDIR="" GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64" GOVCS="" GOVERSION="go1.17.6" GCCGO="gccgo" AR="ar" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="/[REDACTED]/go.mod" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build1498898721=/tmp/go-build -gno-record-gcc-switches"
What did you do?
It is impossible to use errors.Is() with exec.ExitError as the result of a command execution. Consider the following:
import (
"errors"
"log"
"os/exec"
)
var err error
func main() {
var cmd *exec.Cmd
cmd = exec.Command("somecommand", "somearg1")
if err = cmd.Start(); err != nil {
log.Panicln(err)
}
if err = cmd.Wait(); err != nil {
if errors.Is(err, exec.ExitError) { // THIS WILL FAIL SYNTAX, as exec.ExitError.Error() expects a pointer receiver.
_ = "" // Do something here.
}
}
// ...
}Because the structure field values that the *exec.ExitError contains are unpredictable, we cannot do a direct comparison by creating an exec.ExitError to compare against.
Because .Wait() (and .Run, etc.) may return errors other than *exec.ExitError, we can't simply assign the return as an *exec.ExitError (and indeed, the returned is an error interface).
This means in order to simply to determine if it's a runtime non-exec.ExitError error or a non-zero status on Linux (et. al.), one must use typeswitching or typecasting, use errors.As and check the bool of that return with an explicitly declared var for the .As(), or just simply use .Run() and hope that your command returns 0.
This is immensely cumbersome for something that oughtn't be, considering the incredible prevalence of os/exec.Command executions in many third-party libraries.
What did you expect to see?
N/A
What did you see instead?
N/A