New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cmd/go: define error codes and use them to describe errors. #30134

Open
hyangah opened this Issue Feb 8, 2019 · 1 comment

Comments

Projects
None yet
4 participants
@hyangah
Copy link
Contributor

hyangah commented Feb 8, 2019

Go command, particularly, go list and go mod download, now serves as the canonical way to retrieve information about modules and packages. Programs and libraries that need to understand how Go handles build and interprets source code are supposed to invoke the command and interpret the command's output. For example, golang.org/x/tools/go/packages depends on invocation of go list, and we expect some module proxies to utilize go mod download or go list.

Go command provides -json and other flags to output in a structured form to ease the result parsing. But, handling error cases programmatically is still difficult. To be useful like a library, Go command line tool output should allow programs to distinguish different failure cases (invalid arguments, failed precondition, resource unavailability (network, tool, disk, ...) , permission issue, ...).

Currently,

  • Command line exit code: Go command exits with a non-zero exit code for "some" error cases (often 1). But this exit code doesn't carry enough information. Depending on the exit code or error messages from a command line anyway is not a reliable way.

  • Error/Err fields, as in -json or go list -e -f results, provide some error details, but they are "string" types. Parsing and depending on the message is not reliable or scalable.

$ go mod download -json golang.org/x/foo@v1.0.1
{
	"Path": "golang.org/x/foo",
	"Version": "v1.0.1",
	"Error": "unrecognized import path \"golang.org/x/foo\" (parse https://golang.org/x/foo?go-get=1: no go-import meta tags ())"
}
$ go mod download -json golang.org/x/text@v0.3.7
go: finding golang.org/x/text v0.3.7
{
	"Path": "golang.org/x/text",
	"Version": "v0.3.7",
	"Error": "unknown revision v0.3.7"
}

One option is that we define a set of status codes (like https://github.com/grpc/grpc/blob/master/doc/statuscodes.md or like HTTP, JSON error codes)
and use that to describe the kind of the error.

(sidenote: I wished Go2 error proposals also covered encoding/decoding of the error types and root causes but it seems that was not discussed.)

Moreover, we also need to fix the Go command to report the root cause of the error accurately.
For example, I ran the following example while I had not network access. Even though the root cause of the failure is the (temporary) network issue, the error message is not distinguishable from what Go returns when the module does not exists.

$ go list -m --versions --json -e golang.org/x/text
{
        "Path": "golang.org/x/text",
        "Error": {
                "Err": "module \"golang.org/x/text\" is not a known dependency"
        }
}

I am happy to file a separate issue about misleading error messages if there is no existing open issue yet.

@jayconrod @bcmills
@katiehockman @heschik @ianthehat

@andybons andybons added this to the Go1.13 milestone Feb 8, 2019

@jayconrod jayconrod self-assigned this Feb 11, 2019

@rsc

This comment has been minimized.

Copy link
Contributor

rsc commented Feb 14, 2019

In general the go command does not know an accurate error. It ran a helper program like git and that command fails. Trying to pull accurate error analysis out of those helper programs is basically futile.

If the go command return an error code, what would a caller do differently? The right behavior may be just to retry in 1 minute (or 2 or 3 or 5 or whatever, maybe even with exponential backoff) regardless of what went wrong.

I was involved with the great error code page discussions that led to the gRPC HTTP error codes, and honestly I am skeptical that they are that useful in practice. I know the go command does not have available the information necessary to select the right one.

Even "permanent" errors are only permanent until a person fixes them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment