How to check if an error is "deadline exceeded" error?

The cleanest way to do this in Go 1.13+ is using the new errors.Is function.

// Create a context with a very short timeout
ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond)
defer cancel()

// Create the request with it
r, _ := http.NewRequest("GET", "http://example.com", nil)
r = r.WithContext(ctx)

// Do it, it will fail because the request will take longer than 1ms
_, err := http.DefaultClient.Do(r)
log.Println(err) // Get http://example.com: context deadline exceeded

// This prints false, because the http client wraps the context.DeadlineExceeded
// error into another one with extra information.
log.Println(err == context.DeadlineExceeded)

// This prints true, because errors.Is checks all the errors in the wrap chain,
// and returns true if any of them matches.
log.Println(errors.Is(err, context.DeadlineExceeded))

You can determine if an error is the result of a context timeout by comparing the error to context.DeadlineExceeded:

 if err == context.DeadlineExceeded {
     // context deadline exceeded
 }

You can determine if an error is any timeout error using the following function:

func isTimeoutError(err error) bool {
     e, ok := err.(net.Error)
     return ok && e.Timeout()
}

This function returns true all timeout errors including the value context.DeadlineExceeded. That value satisfies the net.Error interface and has a Timeout method that always returns true.

Tags:

Go