Calls to string formatting functions like fmt.Printf seem to be a weak spot for the Go compiler. I end up with lots of bugs (using the wrong formatter after a refactor, forgetting to include all the arguments) that only reveal themselves at runtime. So I end up having to squint hard every time I write one of these.
I did some research today and discovered go tool vet
, which appears to work for fmt.Printf, but it doesn't catch mistakes in errors.Errorf (see below).
import "github.com/pkg/errors"
func ReturnError(s string, i int) error {
// Swap %d and %s, and forget to include the second argument
return errors.Errorf("invalid arguments %d and %s", s)
}
Is there an analog to go tool vet
that can capture string formatting errors in errors.Errorf()? Also, for my own understanding, why is this such a hard problem? It doesn't seem any more difficult for the Go compiler to catch string formatting type errors than any other kind of type errors.
You can tell go vet
which functions to check for (compare godoc.org/cmd/vet):
$ cat x.go
package main
import "github.com/pkg/errors"
func ReturnError(s string, i int) error {
// Swap %d and %s, and forget to include the second argument
return errors.Errorf("invalid arguments %d and %s", s)
}
$ go vet x.go
$ go vet -printfuncs Errorf x.go
# command-line-arguments
./x.go:7: Errorf format %d has arg s of wrong type string
It's not straightforward to do this better for a number of reasons:
fmt.Sprintf(prefix + "%s", ...)
. So it is impossible to catch all invalid format strings at compile time.errors.Errorf
in this case) expects its arguments to behave like fmt.Printf
just by looking at the function definition.