Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a request was cancelled

Tags:

go

I have this simple code in which I try to check if the request was cancelled. But surprisingly, it prints false instead of true in go 1.9.

I wonder what's the correct way to check that?

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
}
like image 485
hgl Avatar asked Nov 08 '17 11:11

hgl


People also ask

How do you check if a context is Cancelled?

The work function is very straightforward. At the start of the function, we test if the context was canceled by checking the ctx. Err() value. If it is not nil, then we exit.

What is context canceled?

In some cases you can see “proxy error: context canceled” error message in the Gateway logs. The error itself means that the connection was closed unexpectedly. It can happen for various reasons, and in some cases it is totally fine: for example client can have unstable mobile internet.


1 Answers

The cleanest way to do this in Go 1.13+ is using the new errors.Is function.

// 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))
like image 140
Dirbaio Avatar answered Nov 03 '22 17:11

Dirbaio