Rumah >pembangunan bahagian belakang >Golang >Bagaimanakah saya boleh menyemak dengan pasti ralat pembatalan permintaan dalam Go, walaupun ia telah dibalut oleh ralat lain?

Bagaimanakah saya boleh menyemak dengan pasti ralat pembatalan permintaan dalam Go, walaupun ia telah dibalut oleh ralat lain?

DDD
DDDasal
2024-11-08 04:08:01357semak imbas

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

Menyemak Pembatalan Permintaan dalam Go

Dalam Go, menentukan sama ada permintaan telah dibatalkan boleh menjadi satu cabaran. Pertimbangkan kod berikut:

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
}

Anehnya, kod ini mencetak palsu dalam Go 1.9 walaupun permintaan itu sepatutnya dibatalkan.

Pendekatan Betul

Dalam versi yang lebih terkini daripada Go, cara yang lebih baik untuk menyemak pembatalan adalah dengan menggunakan fungsi ralat.Adakah yang diperkenalkan dalam Go 1.13. Berikut ialah versi kod yang dikemas kini:

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))
}

Dengan menggunakan ralat.Is, kami boleh menyemak dengan pasti sama ada ralat asas ialah ralat pembatalan konteks, walaupun ia telah dibalut oleh ralat lain. Fungsi errors.Is akan merentasi keseluruhan rantaian ralat dan kembali benar jika mana-mana daripadanya sepadan dengan jenis ralat yang diberikan.

Atas ialah kandungan terperinci Bagaimanakah saya boleh menyemak dengan pasti ralat pembatalan permintaan dalam Go, walaupun ia telah dibalut oleh ralat lain?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn