question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Response.json() never resolves

See original GitHub issue

I have an interesting issue with request that essentially never finishes. It is tricky to reproduce, but everything boils down to proper timing such that there are response headers, but not response body yet.

In such circumstances I’ve uncovered 2 issues:

  1. Timeouts are not propagated to cloned responses, so those never time out (fixed by https://github.com/bitinn/node-fetch/pull/664)
  2. Sometimes even though complete body was received (accumBytes is the same as Content-Length), body.on('end', ...) is never fired

I’m not sure how to fix the second one, one reason may be that response.size is 0 for some reason, looks like it is not read from headers or something. Hopefully maintainers can figure that out.

But at very least with mentioned PR merged it will handle timeouts on cloned response properly.

Reduced example of the code I’m dealing with is like this:

import fetch from "node-fetch";

(async () => {
    const response = await fetch(
        'http://domain.tld/path',
        {
            timeout: 2000,
        },
    );

    console.log(response.status, response.headers);
    console.log(await response.clone().json());
    console.log('This may not be printed ever, without any errors');
})();

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Reactions:12
  • Comments:7 (6 by maintainers)

github_iconTop GitHub Comments

3reactions
bitinncommented, Oct 7, 2019

The correct solution is to resolve cloned response in parallel. See our test cases for an example (search for Promise.all).

The lazy solution is to set a higher water mark during clone, this has been introduced in v3 also.

(From my phone)

On Oct 7, 2019, at 20:52, Nazar Mokrynskyi notifications@github.com wrote:

So the issue is buffer determined by highWaterMark parameter of PassThrough stream. When 2 of those streams are created and only one is read, the buffer of second stream is filled till the limit, after which streaming to both stops until someone consumes data from the second stream.

For instance, this modification works:

const streamBody = new PassThrough(); body.pipe(streamBody); const streamBody2 = new PassThrough(); body.pipe(streamBody2); body = streamBody; streamBody2.on(‘data’, () => {});

return new Body.Promise(function (resolve, reject) { Not sure how to fix it though besides specifying large highWaterMark on PassThrough such that it will fit the whole response body in it.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

2reactions
nazar-pccommented, Oct 7, 2019

Have to reopen, turns out it is still an issue and is related to chunked encoding apparently. So this works fine:

import fetch from "node-fetch";

(async () => {
    const response = await fetch(
        'http://domain.tld/path',
        {
            timeout: 2000,
        },
    );

    console.log(await response.json());
})();

This will timeout if response headers contain Transfer-Encoding: chunked (in my case response from Discord that contains a lot of guild channels, like GET https://discordapp.com/api/v6/guilds/X/channels):

import fetch from "node-fetch";

(async () => {
    const response = await fetch(
        'http://domain.tld/path',
        {
            timeout: 2000,
        },
    );

    response.clone();
    console.log(await response.json());
})();

Still investigating why exactly.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Fetch API not giving response data in Node.js
I have been trying to fix this but it gives me this: ReferenceError: json is not defined.
Read more >
await - JavaScript - MDN Web Docs
The expression is resolved in the same way as Promise.resolve() : it's always converted to a native Promise and then awaited.
Read more >
json() promise never gets resolved in events.js
Hi everyone ! In order to do some debugging, I gathered all my functions in one single piece of code. This is the...
Read more >
Promise - TypeScript Deep Dive
In fact, JSON.parse throws an error if it is passed bad JSON and the callback never gets called and the application crashes. This...
Read more >
Use Promise.all to Stop Async/Await from Blocking ...
Once the response comes back, it resolves a Promise with the data that came back. ... (response) => response.json() ); // .then still...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found