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

ReferenceError: AggregateError is not defined #3205

Open
kaiyoma opened this issue Jun 14, 2021 · 15 comments
Open

ReferenceError: AggregateError is not defined #3205

kaiyoma opened this issue Jun 14, 2021 · 15 comments

Comments

@kaiyoma
Copy link

kaiyoma commented Jun 14, 2021

Basic info:

  • Node.js version: 14.15.5
  • jsdom version: 16.6.0

Minimal reproduction case

I recently upgraded jest-environment-jsdom from 26.6.2 to 27.0.3 and I'm now seeing some issues that I believe are related to this package. If I run multiple test files at once, everything is fine, but if I run a single test file, then there's a crash in this package:

  ● Test suite failed to run

    evalmachine.<anonymous>:1
    AggregateError
    ^

    ReferenceError: AggregateError is not defined

      at evalmachine.<anonymous>:1:1
      at setupWindow (node_modules/jsdom/lib/jsdom/browser/Window.js:111:55)
      at new Window (node_modules/jsdom/lib/jsdom/browser/Window.js:223:3)
      at exports.createWindow (node_modules/jsdom/lib/jsdom/browser/Window.js:95:10)
      at new JSDOM (node_modules/jsdom/lib/api.js:36:20)

I'm not sure what's going wrong here. I've never seen this error before and I can't find any trace of it on the Internet, but after upgrading, everyone on my team is seeing this problem.

I had initially filed this issue here (simon360/jest-environment-jsdom-global#47), but even after purging jest-environment-jsdom-global from the repo, I'm still hitting this crash.

@domenic
Copy link
Member

domenic commented Jun 14, 2021

Unfortunately we can't debug issues that relate to multiple packages outside our control, such as jest-environment-jsdom. Let us know if you come up with reproduction case that just uses jsdom.

@kaiyoma
Copy link
Author

kaiyoma commented Jun 14, 2021

I have no idea how to do that. I'm simply trying to upgrade my testing dependencies to the latest versions and this error is suddenly appearing, with a stack trace that points to this package. Should I file an issue against jest-environment-jsdom?

@domenic
Copy link
Member

domenic commented Jun 14, 2021

Probably!

@kaiyoma
Copy link
Author

kaiyoma commented Jun 15, 2021

@domenic I discovered something very interesting here. I grepped through my node_modules for "AggregateError" and I don't see it referenced in any Jest package. However, I do see it referenced in jsdom:

node_modules/jsdom/lib/jsdom/browser/js-globals.json

Here's the entry:

  "AggregateError": {
    "writable": true,
    "enumerable": false,
    "configurable": true
  },

Not knowing what else to try, I deleted this key entirely, and now my tests pass! The weird error and stack trace have disappeared. Are you positive that this package isn't to blame? All fingers are pointing towards jsdom as the culprit here. The stack trace lists jsdom exclusively and a change to jsdom fixes the problem.

@kaiyoma
Copy link
Author

kaiyoma commented Jun 15, 2021

According to MDN, AggregateError only works in Node 15+:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError

Is there an implicit assumption that all users of jsdom must be on Node 15+? That would be a shock to me, since 14 is the current LTS version.

@TimothyGu
Copy link
Member

@kaiyoma We check the existence of these classes before trying to use them:

const jsGlobalEntriesToInstall = Object.entries(jsGlobals).filter(([name]) => name in global);

Further, we test all LTS versions back to v10 on our CI system. If jsdom by itself no longer working on v10, we would be the first ones to know about it.


The bug could appear when your setup has a combination of following factors:

  1. You are using an older version of Node.js that doesn't support AggregateError. But:
  2. You also have a polyfill or similar that adds its own version of AggregateError to the global object, tricking jsdom into thinking that your Node.js actually supports AggregateError.

Item 2 is crucial here. One way to figure out what library conflicts with jsdom is trying to print the value of global.AggregateError outside any tests. And if it's indeed a function, try printing out global.AggregateError.toString(). At the same time, please also attach the output of npm ls (or yarn list), which displays the dependency tree of your project.

@domenic
Copy link
Member

domenic commented Jun 15, 2021

Honestly, this library could be to blame! We just have no way of knowing without you providing us with a minimal reproducible example that does not involve other libraries. We don't have the time to debug all the interactions with various things people layer on top of jsdom so it's just not something we're interested in.

@kaiyoma
Copy link
Author

kaiyoma commented Jun 15, 2021

It's definitely not item 1, as I'm running Node 14.15.5. Item 2 sounds plausible, though I might need help diagnosing that one. As you suggested, I added some logging (global.AggregateError.toString()) to a non-test tool and this is the output:

function AggregateError() { [native code] }

Here's the output of yarn list: yarn-list.txt

@kaiyoma
Copy link
Author

kaiyoma commented Jun 15, 2021

I spent the day digging into this, and the good news is that I finally figured out what was happening, and it was indeed a polyfill issue.

Context: our Jest config is written in TypeScript, which we load on the fly via a helper script that runs the config through Babel to get ES5/6, which Jest can understand. That helper script loads a few polyfills to do its job, including core-js/stable, which seems to be the culprit here. If I comment out that single import, then all the weird errors go away, so that package must be polyfilling AggregateError.

Lucky for us, our Jest config is comprised entirely of JS primitives, so I can convert it to JSON and avoid this whole transpiling mess entirely. Sorry for the noise, and thank you for the debugging pointers. Your intuition was spot on! And maybe this paper trail will help someone else in the future if they run into a similar issue.

@TimothyGu
Copy link
Member

I think we can be a bit more robust in this scenario regardless.

@TimothyGu TimothyGu reopened this Jun 16, 2021
TimothyGu added a commit that referenced this issue Jun 16, 2021
If we are running on a JavaScript engine that does not natively support
a global in lib/jsdom/browser/js-globals.json, but the user loaded a
polyfill prior to loading jsdom, then we could be tricked into assuming
that global is available in new VM contexts.

Do not assume such a thing, and always check for each global's
availability in the VM context.

One could test this by running the following script on Node.js v14.x,
which does not implement AggregateError natively:

    global.AggregateError = class AggregateError extends Error {};
    const { JSDOM } = require("jsdom");
    new JSDOM("", { runScripts: "dangerously" });

Fixes #3205.
@oakis
Copy link

oakis commented Aug 24, 2021

Any plan to fix this anytime soon?

@termi
Copy link

termi commented Oct 14, 2021

In my case with node@v14.17.4 this problem reproduced with AggregateError polyfill.
This code will failed:

for (const [globalName, globalPropDesc] of jsGlobalEntriesToInstall) {
  const propDesc = { ...globalPropDesc, value: vm.runInContext(globalName, windowInstance) };// <-- vm.runInContext will throw
  Object.defineProperty(windowInstance, globalName, propDesc);
}

The reason of this bug is:

  • ("AggregateError" in global) === true due polyfill.
  • but vm.runInContext('AggregateError', windowInstance) will throw, cause "AggregateError" is not defined in newly created context.

To reproduce, make sure youre version of node doesn't have native AggregateError support.

@termi
Copy link

termi commented Oct 14, 2021

My temporary solution for this issue is to add this in jest.config.js:

const vm = require('vm');
const { createContext } = vm;

/**
 * Temporary solution for issue [jsdom / ReferenceError: AggregateError is not defined]{@link https://github.com/jsdom/jsdom/issues/3205}
 */
function new_createContext(context) {
    if (context && !context.AggregateError && typeof AggregateError === 'function') {
        context.AggregateError = AggregateError;
    }

    return createContext(context);
}

vm.createContext = new_createContext;

@chunkydotdev
Copy link

My temporary solution for this issue is to add this in jest.config.js:

const vm = require('vm');
const { createContext } = vm;

/**
 * Temporary solution for issue [jsdom / ReferenceError: AggregateError is not defined]{@link https://github.com/jsdom/jsdom/issues/3205}
 */
function new_createContext(context) {
    if (context && !context.AggregateError && typeof AggregateError === 'function') {
        context.AggregateError = AggregateError;
    }

    return createContext(context);
}

vm.createContext = new_createContext;

Couldn't get this to work for me unfortunately

@EdoardoRoba
Copy link

Any update on this thread? I am facing the same issue.

I am just seeing this error:
image

Nothing more is displayed.

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

Successfully merging a pull request may close this issue.

7 participants