-
Notifications
You must be signed in to change notification settings - Fork 460
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
invalid character '<' looking for beginning of value #642
Comments
I suspect that |
@yns01 You do know if the the decoding error occurred on the first request or the second? (It looks like the second I think?) |
This one is a variety of improvements to the retry code: * Fixed one bug whereby for a failed request, we were not reading the entire response body before trying to log it, which results in an uninformative output like `&{409....`. Here we add a `ReadAll`. * I denested some code so that we have less indentation. * I changed measuring request time to measuring individual requests around `s.HTTPClient.Do` instead of measuring the entire span including all the sleeping the retry block is doing. * I added logging for the amount of time the program is about to go to sleep before a retry. You can still get the total execution time by adding the time for all requests plus the time for all sleeps. * Generally changed some logs around for consistency around format, casing, and punctuation. The impetus is that I was trying to understand the code to debug #642. This might help get some visibility into a solution, but won't solve the problem.
@yns01 I went through and audited all the retry code here, but it's still not clear to me exactly where your problem is occurring. It looks like what happened here is that you had a first requested which 409ed due to a conflicting request already in flight. The code retried and you got back what looks like a valid response, but decoding failed somewhere (I believe the Can you do two things:
I'm sending #643 through to tighten up some of the logging in this area to make it more legible, but I don't expect it to solve this problem. |
This one is a variety of improvements to the retry code: * Fixed one bug whereby for a failed request, we were not reading the entire response body before trying to log it, which results in an uninformative output like `&{409....`. Here we add a `ReadAll`. * I denested some code so that we have less indentation. * I changed measuring request time to measuring individual requests around `s.HTTPClient.Do` instead of measuring the entire span including all the sleeping the retry block is doing. * I added logging for the amount of time the program is about to go to sleep before a retry. You can still get the total execution time by adding the time for all requests plus the time for all sleeps. * Generally changed some logs around for consistency around format, casing, and punctuation. The impetus is that I was trying to understand the code to debug #642. This might help get some visibility into a solution, but won't solve the problem.
I'll update the package and see how it goes. I think the issue was related to the second requests. I also went through the code and it's not clear to me how it went.
|
Thanks! I just put your JSON through a test and it unmarshals to a charge just fine. Regarding point no. 2 above: could you try to double-check your code elsewhere for |
Thanks; I will. However how would you explain that in the logs there's three requests but I only see two in the dashboard. |
@yns01 The 409 you got back means that the API identified a conflicting request that was still in flight at the time that request was made. That request isn't fully resolved until that conflicting request finishes, and our idempotency layer returns a simple 409 to indicate to the client that there's a conflict and it should retry. |
Well yes - But since the failed request has been retried, I expected at some point to see it in the dashboard. Anyways, here's the logs of another occurrence:
I don't see a possible path in the code to produce these logs.. |
You wouldn't because at that point it'll just be returning a cached response because it's equivalent to your first request — they both shared an idempotency key. It might be a good idea to just step back here and make sure that you're using idempotency keys the way you expect. If you got a 409, that probably means that you reused an idempotency key (see here for docs) for that conflicting request. If you didn't intend to do that, you should look for instances of |
@brandur-stripe I created a repo to reproduce https://github.com/yns01/stripe-go-invalid-char |
@yns01 Thanks. And yep, this one is pretty easy — just remove where you're setting That will fix your code, but there does appear to be an unmarshal problem somewhere still. I'll see if I can track it down. Thanks for the repro! |
I'm sorry, maybe I was not clear at the beginning. But in this case, these are not a different charges. It's meant to be the exact same one, say in case of a retry from the client or a race condition with the webhook handler. Also seen here |
@yns01 Ah yes, thanks Yanis! I get you now. I'm just looking for the problem now, and I think I'm pretty close. |
I actually had a quick look, but I could not figure out why the retry came back with a 400 status code |
Something is pretty wrong here :/ The 400 is actually coming back from the Nginx reverse proxy sitting in front of the API service:
... which explains the unmarshaling problem. I'm not sure why yet. |
This is the body of the second request:
So this where the '<' is coming from Edit: You just posted the same thing |
Yep :/ So wow, you actually stumbled on a bug here that's extremely involved and which stems from our recent addition of HTTP/2 support to The essence of it is that before HTTP/2, it was possible in Go to reuse a In stripe-go, we initialize the We can fix this by setting the |
This patch changes the interfaces of `NewRequest` and `Do` around a little so that we can set a new request body with every request. In the era of HTTP (1), it was safe to reuse a `Request` object, but with the addition of HTTP/2, it's now only sometimes safe. Reusing a `Request` with a body will break. See some more information here: golang/go#19653 (comment) Fixes #642.
This patch changes the interfaces of `NewRequest` and `Do` around a little so that we can set a new request body with every request. In the era of HTTP (1), it was safe to reuse a `Request` object, but with the addition of HTTP/2, it's now only sometimes safe. Reusing a `Request` with a body will break. See some more information here: golang/go#19653 (comment) Fixes #642.
Okay, I have a fix that seems to work out for review in #646. Thanks again for reporting this and the help in tracking it down! Much appreciated. |
This patch changes the interfaces of `NewRequest` and `Do` around a little so that we can set a new request body with every request. In the era of HTTP (1), it was safe to reuse a `Request` object, but with the addition of HTTP/2, it's now only sometimes safe. Reusing a `Request` with a body will break. See some more information here: golang/go#19653 (comment) Fixes #642.
This patch changes the interfaces of `NewRequest` and `Do` around a little so that we can set a new request body with every request. In the era of HTTP (1), it was safe to reuse a `Request` object, but with the addition of HTTP/2, it's now only sometimes safe. Reusing a `Request` with a body will break. See some more information here: golang/go#19653 (comment) Fixes #642.
It was a tricky one, I hard a hard time tracking it down |
Well, thanks for the effort :$ Very tricky problem for sure. I've released this as a major (39.0.0) because technically it changes some exported interfaces in a backward compatible way, but the upgrade should be trivial to most users. |
Bumps [pg](https://github.com/ged/ruby-pg) from 1.4.2 to 1.4.3. - [Release notes](https://github.com/ged/ruby-pg/releases) - [Changelog](https://github.com/ged/ruby-pg/blob/master/History.rdoc) - [Commits](ged/ruby-pg@v1.4.2...v1.4.3) --- updated-dependencies: - dependency-name: pg dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Hey,
Some requests are failing with the following error:
invalid character '<' looking for beginning of value
I configured the number of retries to 3. Here's a timeline of what happened:
On the Stripe dashboard:
On my logs with
LogLevel = 5
:One of the two requests ended with a 409 and was retried and failed with the error in the title. As it does not appear on the dashboard, it seems it did not reach your servers.
AFAIK, it should have been retried.
Similar but maybe not related to #528
go version: 1.10.1
stripe-go: 35.1.0
Thanks!
The text was updated successfully, but these errors were encountered: