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.

Invalid state: Controller is already closed

See original GitHub issue

Bug Description

When running my tests with undici v5.8.0 I am getting the traceback:

node:internal/errors:466
    ErrorCaptureStackTrace(err);
    ^

TypeError: Invalid state: Controller is already closed
    at new NodeError (node:internal/errors:377:5)
    at ReadableStreamDefaultController.enqueue (node:internal/webstreams/readablestream:992:13)
    at Fetch.fetchParams.controller.resume (/Users/fz/projects/centrifugal/centrifuge-js/node_modules/undici/lib/fetch/index.js:1864:41)
    at processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 'ERR_INVALID_STATE'

I did some research if this can be helpful:

In my case the code in undici is getting exception in calling await fetchParams.controller.next() in lib/fetch/index.js, so catch branch works:

      try {
        const { done, value } = await fetchParams.controller.next()

        if (isAborted(fetchParams)) {
          break
        }

        bytes = done ? undefined : value
      } catch (err) {
        if (fetchParams.controller.ended && !timingInfo.encodedBodySize) {
          // zlib doesn't like empty streams.
          bytes = undefined
        } else {
          bytes = err
        }
      }

I added some console logging:

      } catch (err) {
        console.log(err); // DOMException [AbortError]: The operation was aborted.
        console.log(fetchParams.controller.ended); // undefined
        console.log(timingInfo.encodedBodySize); // 136
        console.log(fetchParams.controller.ended && !timingInfo.encodedBodySize); // undefined
        if (fetchParams.controller.ended && !timingInfo.encodedBodySize) {
          // zlib doesn't like empty streams.
          bytes = undefined
        } else {
          console.log("bytes is err"); // bytes is err
          bytes = err
          console.log(bytes instanceof Error); // false
          console.log(typeof bytes); // object
        }
      }

The detailed exception is:

DOMException [AbortError]: The operation was aborted.
        at new DOMException (node:internal/per_context/domexception:51:5)
        at Fetch.abort (/Users/fz/projects/centrifugal/centrifuge-js/node_modules/undici/lib/fetch/index.js:89:20)
        at AbortSignal.requestObject.signal.addEventListener.once (/Users/fz/projects/centrifugal/centrifuge-js/node_modules/undici/lib/fetch/index.js:165:20)
        at AbortSignal.[nodejs.internal.kHybridDispatch] (node:internal/event_target:639:20)
        at AbortSignal.dispatchEvent (node:internal/event_target:581:26)
        at abortSignal (node:internal/abort_controller:291:10)
        at AbortController.abort (node:internal/abort_controller:321:5)
        at AbortSignal.abort (/Users/fz/projects/centrifugal/centrifuge-js/node_modules/undici/lib/fetch/request.js:372:32)
        at AbortSignal.[nodejs.internal.kHybridDispatch] (node:internal/event_target:639:20)
        at AbortSignal.dispatchEvent (node:internal/event_target:581:26)

So I suppose fetchParams.controller.controller.enqueue(new Uint8Array(bytes)) is called even if the stream was aborted.

Reproducible By

Create a new Node project with npm init

Add jest:

npm install --save-dev jest

Add test file index.test.js:

test('test exception', async () => {
    const d = new DOMException('test')
    expect(d).toBeInstanceOf(Error)
    expect(d instanceof Error).toBeTruthy()
})

Update package.json to have:

{
  "scripts": {
    "test": "jest"
  }
}

Run npm test

Expected Behavior

DOMException in Jest env does not extend Error, so stream aborting logic in https://github.com/nodejs/undici/blob/26f60b7b6e612bb831133d7f85914963d1955011/lib/fetch/index.js#L1857 does not work.

Environment

Node v18.2.0

Running tests with jest

Additional context

This reproduces starting from undici v5.6.0

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:10 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
KhafraDevcommented, Jul 20, 2022

Jest has had an issue with instanceof Error for over half a decade now, this will most likely need to be fixed here. I’ll work on this tomorrow.

0reactions
FZambiacommented, Jul 21, 2022

Many thanks for helping with this, I tried to run tests with undici from the latest commit and it worked fine.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unhandled Exception: Bad state: Cannot add new events after ...
The controller becomes closed by calling the close method. New events cannot be added, by calling add or addError, to a closed controller....
Read more >
Frequently Asked Questions about Payments Issued by the ...
The State Controller's Office (SCO) prepares and releases warrants (another word for checks or payments) and electronic fund transfers from the State ...
Read more >
AP can't join. DTLS connection closed by controller
I haven't consoled into AP yet. I'll do it now and post the outputs. First I connected 3 APs and then disconnected 2...
Read more >
Bad state: Cannot add new events after calling close-Flutter
The controller becomes closed by calling the close method. New events cannot be added, by calling add or addError, to a closed controller....
Read more >
ISteamNetworkingSockets Interface - Steamworks
The same connections are still used under the hood, so you still get the same ... k_EResultInvalidState if the connection is not in...
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