go version go1.15.5 darwin/amd64
OS: macOS Catalina 10.15.7
Does this issue reproduce with the latest release?
Yes. Just do any request on canceled context.
What did you do?
Hi there. I got undefined behaviour of stdlib http client. The library (stripe-go) uses stdlib and relies on cancelation of request by context.Context.
For some local tests I cancel passed Context manually (no timeout) calling cancel() method and then call Stripe library. I was surprised to get result together:
1) Stripe got an request and perform action
2) I got an error and will retry (thanks for idempotency key that will not cause double charging of customer)
Could you implement some cs.completelyWritten() check and don't return error in case of body completed written? Or maybe reset Context and don't process ctx.Done for case if it happen in last nanosecond or even with already written as in my case. Or maybe even check ctx.Err() before request just for test cases here: https://github.com/golang/go/blob/212d385a2f723a8dd5e7d2e83efb478ddd139349/src/net/http/h2_bundle.go#L7638
My point is - don't return error for allow to do fewer count of retries. Unfortunately stripe-go used a retry for request with canceled so chance to send request was multiplied by retry count. It was fixed in recent: https://github.com/stripe/stripe-go/issues/1184
And yes I understand about sent request is not guarantee and we can get error while reading response. But stdlib should give guarantee with predefined environment I think.
And one question more: is it documented behaviour? I will mail Stripe with this issue link . Maybe that's better to check ctx.Err() on their side before sending request with already canceled context.
What did you expect to see?
Sent request or error. No both together.
What did you see instead?
Server receive and process request && I got an error (context canceled) from library (not by reading response)
I need in one more retry and should implement Idempotency key
What version of Go are you using (go version)?
Does this issue reproduce with the latest release? Yes. Just do any request on canceled context.
What did you do?
Hi there. I got undefined behaviour of stdlib http client. The library (stripe-go) uses stdlib and relies on cancelation of request by context.Context. For some local tests I cancel passed Context manually (no timeout) calling cancel() method and then call Stripe library. I was surprised to get result together: 1) Stripe got an request and perform action 2) I got an error and will retry (thanks for idempotency key that will not cause double charging of customer)
Problem code here in function named
roundTrip
: https://github.com/golang/go/blob/212d385a2f723a8dd5e7d2e83efb478ddd139349/src/net/http/h2_bundle.go#L7535Select statement don't guarantee of execution order. So with manually canceled context before request I got: 1) first write body here (request sent): https://github.com/golang/go/blob/212d385a2f723a8dd5e7d2e83efb478ddd139349/src/net/http/h2_bundle.go#L7700 2) next execution code here that returns
cs.getStartedWrite() == true
and error(context canceled)
https://github.com/golang/go/blob/212d385a2f723a8dd5e7d2e83efb478ddd139349/src/net/http/h2_bundle.go#L7677Could you implement some
cs.completelyWritten()
check and don't return error in case of body completed written? Or maybe reset Context and don't processctx.Done
for case if it happen in last nanosecond or even with already written as in my case. Or maybe even checkctx.Err()
before request just for test cases here: https://github.com/golang/go/blob/212d385a2f723a8dd5e7d2e83efb478ddd139349/src/net/http/h2_bundle.go#L7638My point is - don't return error for allow to do fewer count of retries. Unfortunately stripe-go used a retry for request with canceled so chance to send request was multiplied by retry count. It was fixed in recent: https://github.com/stripe/stripe-go/issues/1184 And yes I understand about sent request is not guarantee and we can get error while reading response. But stdlib should give guarantee with predefined environment I think. And one question more: is it documented behaviour? I will mail Stripe with this issue link . Maybe that's better to check
ctx.Err()
on their side before sending request with already canceled context.What did you expect to see? Sent request or error. No both together.
What did you see instead? Server receive and process request && I got an error
(context canceled)
from library (not by reading response) I need in one more retry and should implement Idempotency key