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