ホームページ  >  記事  >  バックエンド開発  >  別のエラーによってラップされている場合でも、Go でリクエストキャンセルエラーを確実に確認するにはどうすればよいですか?

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

DDD
DDDオリジナル
2024-11-08 04:08:01253ブラウズ

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。