"err declared but not used" with multiple errors

Issue

If I have a program like this:

package main
import "strconv"

func main() {
   a, err := strconv.Atoi("100")
   println(a)
}

I get this result, as expected:

.\file.go:5:7: err declared but not used

However this program:

package main
import "strconv"

func main() {
   a, err := strconv.Atoi("100")
   if err != nil {
      panic(err)
   }
   b, err := strconv.Atoi("100")
   println(a, b)
}

Compiles without error, even though I never checked the second err value. Why does this happen? Also, can I change some option, so that these mistakes result in compile time errors or warnings?

Solution

This is because in the second case you are re-using an existing err variable, so it is being used. Despite the := instantiate & assign operator, a new err variable is not instantiated.

If you named the errors differently, such as this:

func main() {
   a, err := strconv.Atoi("100")
   if err != nil {
      panic(err)
   }
   b, err2 := strconv.Atoi("100")
   println(a, b)
}

Then you would see a compile error for both cases.

If you don’t want to change your code but also still want to be notified of this issue, you will need to rely on a go linter instead of the go compiler. Go has a very robust ecosystem of linters so I won’t recommend one in particular, but at my organization I would see an error like this from our linter if I were to write such code:

scratch/test.go:10:2: ineffectual assignment to err (ineffassign)
           b, err := strconv.Atoi("100")

Answered By – ThePorkchopExpress

Answer Checked By – David Goodson (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.