Idiomatic error filtering in Go

The error type in Go is quite wide, and the actual type can vary both on the platform and between versions. Is it idiomatic to filter the errors that we expect from the value of the error string, error.Error() ?

For instance:

 _, err := conn.Write(b) if err != nil { if !strings.Contains(err.Error(), "peer reset") { log.Print(err) } return } 

Is there a better way to do this?

+5
source share
1 answer

I'm not sure I'm saying something you don’t know, but I have seen several ways to deal with this: compare with known instances when they are exported and appear in godoc, for example io.EOF or os.ErrNotExist ; using type statements or switches when documents promise a certain type of error, for example *os.PathError or *os.LinkError ; or discarding messages. The first should be clear enough, and you have made the third in your question; type checking might look like this:

 if pathErr, ok := err.(*os.PathError); ok { log.Fatal("Bad path " + pathErr.Path + ", giving up") } else if err != nil { return err } 

I think this would be rare, but if you had several potential types, you could use a type switch:

 switch err.(type) { case *os.PathError, *os.LinkError: log.Fatal("oof") case nil: // nothing; prevents default default: log.Fatal("huh") } 

(The choice of error and behavior here is a bit silly - I'm just trying to expose a template with syntax.)

The tough part that you refer to in your question: it may not be clear what guarantees you have about which errors will be returned. I know that, for example, release notes for 1.5 say that they standardize more on net.OpError for pure errors than before, but that’s all I know. The custody at the source of the package that you call or ask people can be fine if there are important cases that you think are unclear.

+1
source

All Articles