在golang中正确处理context.deadlineExceededError。

huangapple go评论78阅读模式
英文:

Correctly handle context.deadlineExceededError in golang

问题

在异常处理的switch语句中,有没有一种方法可以通过类型匹配golang的context deadline exceeded错误?

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

由于无法引用未导出的名称context.deadlineExceededError,这段代码无法编译通过。

cannot refer to unexported name context.deadlineExceededError

根据我所看到的情况,由于该类型未导出,只能通过字符串比较来处理。

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

与字符串比较相比:

        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
英文:

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(&quot;deadline exceeded&quot;)
}

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 (
        &quot;context&quot;
        &quot;fmt&quot;
        &quot;time&quot;
)

const shortDuration = 1 * time.Second

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

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

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

vs string comparison

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

答案1

得分: 2

你可以使用context.DeadlineExceeded值(文档):

  • 可以直接使用err == context.DeadlineExceeded进行比较,
  • 或者使用errors.Is(err, context.DeadlineExceeded)
英文:

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

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

huangapple
  • 本文由 发表于 2022年6月10日 13:16:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/72569384.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定