Home > database >  Correctly handle context.deadlineExceededError in golang
Correctly handle context.deadlineExceededError in golang

Time:06-13

Is there a way to match a golang context deadline exceeded error by type in an exception handling switch?

switch err.(type)
case context.deadlineExceededError:
  fmt.Println("deadline exceeded")
}

won't compile, due to

cannot refer to unexported name context.deadlineExceededError

AFAICS since the type isn't exported, it can only be handled by string comparison.

package main

import (
        "context"
        "fmt"
        "time"
)

const shortDuration = 1 * time.Second

func main() {
        ctx, cancel := context.WithTimeout(context.Background(), shortDuration)
        defer cancel()

        select {
        case <-time.After(shortDuration*2):
                fmt.Println("overslept")
        case <-ctx.Done():
                err := ctx.Err()
                switch err.(type) {
                case context.deadlineExceededError:
                        fmt.Println("deadline")
                }
                fmt.Printf("error %T: %v\n", err, err)
        }

}
$ go build main.go
# command-line-arguments
./main.go:21:8: cannot refer to unexported name context.deadlineExceededError

vs string comparison

        case <-ctx.Done():
                err := ctx.Err()
                errType := fmt.Sprintf("%T",err)
                switch errType {
                case "context.deadlineExceededError":
                        fmt.Println("deadline")
                }
                fmt.Printf("error %T: %v\n", err, err)
        }
$ go build main.go && ./main
deadline
error context.deadlineExceededError: context deadline exceeded

CodePudding user response:

You can use the context.DeadlineExceeded value (documentation):

  • either for direct err == context.DeadlineExceeded comparison,
  • or using errors.Is(err, context.DeadlineExceeded).
  •  Tags:  
  • go
  • Related