Skip to content
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

retry not working with POST (with OPTIONS preflight) and 401 statuscode #230

Closed
DanielRuf opened this issue Jan 30, 2020 · 13 comments
Closed

Comments

@DanielRuf
Copy link

We have the following retry options:

const retryOptions = {
        limit: 10,
        methods: ['post'],
        statusCodes: [401, 500, 502]
};

I generate a 401 error from the backend and I see it also as 401 statuscode in the developer tools of the browser.

But it does not retry the failing request:

const response = await ky.post(`${API_ENDPOINT}/users`, {
            json: {
                accessToken: accessToken
            },
            retry: retryOptions
        }).json();
        return response;

Any idea why?
The docs are not very helpful here.

Is post not supported there?

@DanielRuf
Copy link
Author

Ah, some debugging in the node_modules/ky/index.js reveals:

retry error TypeError: "Body has already been consumed."

@DanielRuf
Copy link
Author

I think we have to do the json() call in a separate line.

@DanielRuf
Copy link
Author

Hm, now it is retry error HTTPError: "Unauthorized" and after that the retry error TypeError: "Body has already been consumed."

@DanielRuf
Copy link
Author

DanielRuf commented Jan 30, 2020

This thrown by these lines:

if (this._options.timeout === false) {
      return globals.fetch(this.request);
    }

    return timeout(globals.fetch(this.request), this._options.timeout, this.abortController);

@DanielRuf
Copy link
Author

So for me it seems POST is not suppported right now.

@sholladay
Copy link
Collaborator

sholladay commented Jan 30, 2020

Hi @DanielRuf, thanks for the bug report. Your use case is officially supported, however v0.16 has a regression related to constructing the request that prevents retries from working when the request has a body. This is a known issue.

We need to fix Ky by calling this.request.clone() everywhere we reuse a request, which I plan to implement soon (but feel free to make a PR if you need this fixed quickly).

Until such a fix is released, if this feature is important to you, you may want to stay on v0.15.

@sholladay
Copy link
Collaborator

Duplicate of #217

@sholladay sholladay marked this as a duplicate of #217 Jan 30, 2020
@sholladay sholladay reopened this Jan 30, 2020
@DanielRuf
Copy link
Author

We've migrated to simple get requests and moved the body to custom headers which works without any issues as this issue is a blocker for us.

@DanielRuf
Copy link
Author

I do not see where it is related to #217 as we have different errors which are only because of the POST body. Or is this what is also caused by the regression and solved by cloning the request?

Because this is not clear in #217 =)

@sholladay
Copy link
Collaborator

You mentioned seeing TypeError: "Body has already been consumed.". This is the error that #217 is all about, hence why I marked this as a duplicate. I think it is the root cause of your issue, since it prevents retries from working when the request has a body.

Retries should still work with any request that does not have a body, including POST requests (assuming you opt-in to retrying POST).

@DanielRuf
Copy link
Author

You mentioned seeing TypeError: "Body has already been consumed.". This is the error that #217 is all about,

I do not see where it is related to #217

A simple ctrl f does not show any result for Body has already been consumed, that's why I am asking ;-) Even no result for consumed and body.

@sholladay
Copy link
Collaborator

You are using Firefox whereas they are using Chrome, so the message is slightly different... sorry it's not standardized. 😄

TypeError: "Body has already been consumed."

vs

TypeError: Failed to execute 'fetch' on 'Window': Cannot construct a Request with a Request object that has already been used.

These messages are for the same error condition, here's a minimal repro that you can run in the console of both browsers to prove it:

const req = new Request('/foo', { method : 'POST', body : 'foo' });
fetch(req);
fetch(req);

I just submitted a fix for this in PR #231. You can try using that branch and check that it does indeed work for your use case (you'll have to load the dependency from GitHub, which you can do with npm or by importing the raw GitHub URL in the browser).

@DanielRuf
Copy link
Author

DanielRuf commented Jan 30, 2020

Ah, thanks for the clarification. That makes sense now =)
Sigh, I hope we get consistent error messages in browsers :D

Or people can try it with patch-package and use https://github.com/sindresorhus/ky/pull/231.patch ;-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants