Check for error status codes with Golang exec

Viewed 65

I currently have some basic Go code running with the following:

    var test = errors.New("exit status 127")

    cmd := exec.Command("sh", "-c", "'exit 3'")
    err := cmd.Run()
    fmt.Printf("%v\n", err)
    fmt.Printf("%v\n", test)
    if errors.Is(err, test) {
        fmt.Printf("Ahh found error\n")
    }

Now the output is as follows:

exit status 127
exit status 127

Program exited.

I think I am misunderstanding how errors.Is works as I would expect the code above to output Ahh found error as both errors are the same.

Can anyone explain why errors.Is(err, test) is not true in this instance?

Go Playground Link: https://go.dev/play/p/4MQEvljdz53


Update: This question was marked as duplicate because I was not clear enough with my question. The question should have been "How do I check for error status codes when using Go's "exec" package?" using the example of exit status 127

1 Answers

When you check an error with errors.Is(), it does not compare the strings, but rather the actual error values. Go's error type is actually an interface with an Error() string method.

If you want to check the exit code, you'll have to get the concrete error value returned by cmd.Run(). According to the documentation, *exec.ExitError will be returned if the command doesn't complete successfully. ExitError's documentation shows that it contains *os.ProcessState, which has an ExitCode() method.

Therefore, you can check the exit code by doing this:

err := cmd.Run()
// Do a type assertion to check the interface's concrete type
if err, ok := err.(*exec.ExitError); ok {

    // Since the ProcessState had no name, it was embedded.
    // This means you can call its methods as if they were
    // on ExitError itself.
    code := err.ExitCode()
    if code == 127 {
        // do something
    }
}
Related