镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

v14.10.0 changes behavior of existing code (got) #35116

Description

@benjamincburns
  • Version: v14.10.0
  • Platform: All
  • Subsystem: Uncertain

What steps will reproduce the bug?

got@11.6.1 hangs when running under v14.10.0. Works fine under earlier versions, including v14.9.0. See sindresorhus/got#1441 for more details.

As v14.10.0 was a minor version bump, I wouldn't expect it to break existing code.

How often does it reproduce? Is there a required condition?

Every time.

What is the expected behavior?

got can make a request successfully

What do you see instead?

got hangs indefinitely (promise doesn't resolve - not sure why)

Additional information

got has over 12 million weekly downloads. This issue should probably be addressed quickly.

Activity

  1. targos commented on Sep 9, 2020

    @targos
    Member

    Reproduction:

    require('got')('https://www.google.com').then(console.log, console.log)

    This logs the response in Node.js 14.9.0 and exits without any logs in Node.js 14.10.0

  2. targos commented on Sep 9, 2020

    @targos
    Member

    I'm bisecting...

  3. targos commented on Sep 9, 2020

    @targos
    Member

    4bb4007 is the first bad commit
    Author: Robert Nagy @ronag
    Date: Tue Jun 23 23:08:14 2020 +0200

    stream: simpler and faster Readable async iterator
    
    Reimplement as an async generator instead of a custom
    iterator class.
    
    Backport-PR-URL: https://github.com/nodejs/node/pull/34887
    PR-URL: https://github.com/nodejs/node/pull/34035
    Refs: https://github.com/nodejs/node/issues/34680
    Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
    Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
    Reviewed-By: James M Snell <jasnell@gmail.com>
    
  4. ronag commented on Sep 9, 2020

    @ronag
    Member

    Would someone mind to dig into this a bit a look exactly where in got the problem occurs? I'm a bit swamped today but might be able to take a look if I know more specifically where e.g. async generators come into play?

  5. ronag commented on Sep 9, 2020

    @ronag
    Member

    Should got be added to CITGM?

  6. targos commented on Sep 9, 2020

    @targos
    Member

    Got was disabled in CITGM because there were issues with ESLint that made it always fail: nodejs/citgm#825, nodejs/citgm#795

  7. targos commented on Sep 9, 2020

    @targos
    Member

    This happens because got treats calls to Stream#_destroy as error cases:

    https://github.com/sindresorhus/got/blob/408e22aed99300afd4af49a4eb50963665d8a144/source/core/index.ts#L2666-L2691

    The promise never resolves because _isAboutToError is checked to return early here:

    https://github.com/sindresorhus/got/blob/1f132e88b4e9b295631637757d64307032a4e56e/source/as-promise/index.ts#L63-L65

    The _destroy method is called from here:

    node/lib/_stream_readable.js

    Lines 1117 to 1119 in 1204400

    } finally {
    destroyImpl.destroyer(stream, null);
    }

  8. ronag commented on Sep 9, 2020

    @ronag
  9. ronag commented on Sep 9, 2020

    @ronag
    Member

    Ok, this might actually be an error in the PR. We should not call destroy before end has been emitted.

    I'll try to prepare a PR tonight.

    If someone wants to work on it asap something like this should fix it:

      try {
        const state = stream._readableState;
        while (true) {
          const chunk = stream.read();
          if (chunk !== null) {
            yield chunk;
          } else if (state.errored) {
            throw state.errored;
          } else if (state.endEmitted) {
            break;
          } else if (state.closed) {
            // TODO(ronag): ERR_PREMATURE_CLOSE?
            break;
          } else {
            await new Promise(next);
          }
        }
      } catch (err) {
        destroyImpl.destroyer(stream, err);
        throw err;
      } finally {
        destroyImpl.destroyer(stream, null);
      }

    i.e. change state.ended to state.endEmitted.

  10. ronag commented on Sep 9, 2020

    @ronag
    Member

    I'm not sure whether the above will resolve the referenced issue though.

  11. richardlau commented on Sep 9, 2020

    @richardlau
    Member

    I'm not sure whether the above will resolve the referenced issue though.

    I've just tested it and it does not 😞.

    Got was disabled in CITGM because there were issues with ESLint that made it always fail: nodejs/citgm#825, nodejs/citgm#795

    We should unskip it in the lookup if we can. FWIW you can run "citgm got" instead of "citgm-all" to still test the module, e.g. against the current master branch: https://ci.nodejs.org/job/citgm-smoker/2461/

    Edit: CI contains lint warnings similar to nodejs/citgm#795 but the test is also timed out.

  12. richardlau commented on Sep 9, 2020

    @richardlau
    Member

    Unfortunately it looks like got still times out with #35120. It's not clear to me if this is thought to be an issue with got itself (#35116 (comment)) or is something we need to push a new release for (cc @nodejs/streams).

    If we do need to push a new release we should aim to do that by tomorrow (Thursday 10th September) at the latest since:

    • There are security releases due out next Tuesday and one of the vulnerabilities being addressed in v14.x is rated as critical severity. We should aim to not block people from picking up the security release if it's going to break them.
    • We have a policy of not releasing on a Friday.

    I can push out a new release if required. Questions:

    cc @nodejs/releasers @nodejs/tsc

  13. ronag commented on Sep 9, 2020

    @ronag
    Member

    I think I've managed to figure out the problem. The old async iterator didn't destroy on success and got assumes destroy is an error.

    I will try to sort out a PR.

  14. szmarczak commented on Sep 9, 2020

    @szmarczak
    Member

    @targos is right. The _isAboutToError check is done on the response event after the body has been read. If ClientRequest Got stream has autoDestroy set to true, then it will hang because it assumes it's an error. I'll fix this in a few hours.

  15. szmarczak commented on Sep 9, 2020

    @szmarczak
    Member

    So @ronag is also right. Node.js 14.10.0 broke autoDestroy. But since it is highly recommend that it is set to true, I will fix this on Got side anyway. Unfortunately it has to remain as false. The fix is quite complicated and we would need to release a breaking major change.

  16. richardlau commented on Sep 10, 2020

    @richardlau
    Member

    I've opened a proposal for a v14.10.1 (#35137) that reverts 4bb4007. It sounds like we'll need more time to address the issues being seen, and reverting the commit gets the got tests passing with CITGM on at least some platforms (before it was failing across the board).

  17. MylesBorins commented on Sep 10, 2020

    @MylesBorins
    Contributor

    @richardlau should we be reverting from master as well?

  18. mcollina commented on Sep 10, 2020

    @mcollina
    SponsorMember

    it will hang because it assumes it's an error. I'll fix this in a few hours.

    @szmarczak note that this is a bug on got side. .destroy() is not an error-generating scenario, .destroy(err) is.


    @MylesBorins it should be reverted in v14 and then fixed on master and v15.

  19. ronag commented on Sep 10, 2020

    @ronag
    Member

    @joaopaulobdac would you mind providing a complete example? Are you also using got?

  20. szmarczak commented on Sep 10, 2020

    @szmarczak
    Member

    @szmarczak note that this is a bug on got side. .destroy() is not an error-generating scenario, .destroy(err) is.

    Why is it so? autoDestroy is false so it shouldn't call .destroy(), therefore _isAboutToError would return false. I'm fully aware that Got incorrectly throws even after the Got stream is destroyed. To use autoDestroy it needs to be a breaking major release for Got (unless I find some other way to do stuff)

  21. ronag commented on Sep 10, 2020

    @ronag
    Member

    @joaopaulobdac That's great information! Any chance you could share a minimal reproducible example?

  22. ronag commented on Sep 10, 2020

    @ronag
    Member

    @szmarczak We are reverting the change. There is a problem with got but as you said we should not cause such a breaking change in semver-minor. I'm sorry for the inconvenience this has caused. Did not consider this.

    That being said I'd very much appreciate if you could continue helping with a fix in v15 and making got pass in CITGM.

  23. szmarczak commented on Sep 10, 2020

    @szmarczak
    Member

    There is a problem with got but as you said we should not cause such a breaking change in semver-minor.

    I meant that if Got was to use autoDestroy: true then we should do a major release at Got.

    I'm sorry for the inconvenience this has caused. Did not consider this.

    No problem. I'm glad that we see this "bug" sooner than later :D

    That being said I'd very much appreciate if you could continue helping with a fix in v15 and making got pass in CITGM.

    I've been actually debugging for ~10 mins and have no thoughts to stop. I'm continuing :)

  24. added
    httpIssues and PRs related to the http subsystem.
    on Oct 22, 2020
  25. ronag commented on Oct 23, 2020

    @ronag
    Member

    I believe this has been resolved in latest 14.x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    httpIssues and PRs related to the http subsystem.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions