24

For example, I am using one Go standard library function as:

func Dial(network, address string) (*Client, error)

This function may return errors, and I just care about errors which report "connection lost" or "connection refused", then do some code to fix these.
It seems like:

client, err := rpc.Dial("tcp", ":1234")  
if err == KindOf(ConnectionRefused) {
  // do something
}

What's more, how to get all the errors a specific standard library function may return?

2

2 Answers 2

17

In modern Go, the best general way to do this is with the errors.Is and errors.As functions in the standard library.

For the example in the original question, this is quite straight forward:

if errors.Is(err, syscall.ECONNREFUSED) {
    // Connection refused error
} else {
    // Some other kind of error
}

However, this only works for errors which are properly wrapped/created to use these capabilities. Sometimes you may need to mix-and-match the use of errors.Is and errors.As with string comparison. I've made a video that goes into some of these details for those interested.


My old answer:

There's no standard way to do this.

The most obvious way, which should only be used if no other method is available, is to compare the error string against what you expect:

if err.Error() == "connection lost" { ... }

Or perhaps more robust in some situations:

if strings.HasSuffix(err.Error(), ": connection lost") { ... }

But many libraries will return specific error types, which makes this much easier.

In your case, what's relevant are the various error types exported by the net package: AddrError, DNSConfigError, DNSError, Error, etc.

You probably care most about net.Error, which is used for network errors. So you could check thusly:

if _, ok := err.(net.Error); ok {
    // You know it's a net.Error instance
    if err.Error() == "connection lost" { ... }
}

What's more, how to get all the errors a specific standard library function may return?

The only fool-proof way to do this is to read the source for the library. Before going to that extreme, a first step is simply to read the godoc, as in the case of the net package, the errors are pretty well documented.

Sign up to request clarification or add additional context in comments.

2 Comments

what is this err.(net.Error) syntax?
@JBaczuk: That's a type assertion. If the error's underlying type is net.Error, ok will evaluate as true.
5

You can now use the errors.Is() function to compare some standard errors:

client, err := net.Dial("tcp", ":1234")
if errors.Is(err, net.ErrClosed) {
    fmt.Println("connection has been closed.")
}

A common file opening scenario:

file, err := os.Open("non-existing");
if err != nil {
    if errors.Is(err, fs.ErrNotExist) {
        fmt.Println("file does not exist")
    } else {
        fmt.Println(err)
    }
}

UPDATE
You can also use errors.As() if you'd like to check the error type:

client, err := net.Dial("tcp", ":1234")
var errC = net.ErrClosed
if errors.As(err, &errC) {
    fmt.Printf("connection has been closed: %s", errC)
}
client.Close()

A more detailed explanation can be found in the Go Blog.

1 Comment

For what OP is asking about specifically, I think either works. But in general, errors.As gives you a lot more leeway to check very specific error properties. In 2025, this is the best answer IMO

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.