別のエラーによってラップされている場合でも、Go でリクエストキャンセルエラーを確実に確認するにはどうすればよいですか?

DDD
リリース: 2024-11-08 04:08:01
オリジナル
184 人が閲覧しました

How do I reliably check for a request cancellation error in Go, even if it has been wrapped by another error?

Go でリクエストのキャンセルを確認する

Go では、リクエストがキャンセルされたかどうかを判断するのが難しい場合があります。次のコードを考えてみましょう。

package main

import (
    "context"
    "log"
    "net/http"
)

func main() {
    r, _ := http.NewRequest("GET", "http://example.com", nil)
    ctx, cancel := context.WithCancel(context.Background())
    r = r.WithContext(ctx)
    ch := make(chan bool)
    go func() {
        _, err := http.DefaultClient.Do(r)
        log.Println(err == context.Canceled)
        ch <- true
    }()
    cancel()
    <-ch
}
ログイン後にコピー

驚くべきことに、このコードは、リクエストがキャンセルされるはずであるにもかかわらず、Go 1.9 では false を出力します。

正しいアプローチ

より新しいバージョンではGo では、キャンセルを確認するより良い方法は、Go 1.13 で導入されたerrors.Is 関数を使用することです。コードの更新バージョンは次のとおりです。

import (
    "context"
    "errors"
    "log"
    "net/http"
)

func main() {
    // Create a context that is already canceled
    ctx, cancel := context.WithCancel(context.Background())
    cancel()

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

    // Do it, it will immediately fail because the context is canceled.
    _, err := http.DefaultClient.Do(r)
    log.Println(err) // Get http://example.com: context canceled

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

    // 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.Canceled))
}
ログイン後にコピー

errors.Is を使用すると、別のエラーによってラップされている場合でも、基になるエラーがコンテキスト キャンセル エラーであるかどうかを確実に確認できます。 errors.Is 関数は、エラーのチェーン全体を調べ、それらのいずれかが指定されたエラー タイプに一致する場合に true を返します。

以上が別のエラーによってラップされている場合でも、Go でリクエストキャンセルエラーを確実に確認するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!