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

"cannot coerce undefined to object" - Spread into array syntax issues #140

Closed
lll000111 opened this issue Mar 8, 2019 · 5 comments
Closed
Labels
fixed - please verify Issue has been fixed. Please verify and close.

Comments

@lll000111
Copy link

lll000111 commented Mar 8, 2019

EDIT Very small reproducible example added in a comment below.


I have a weird problem that running in isolation works just fine.

Code

(Excerpt)

  if (thing.referenceTo !== undefined) {
    trace(thing.referenceTo + '\n');
    for (let entry of thing.referenceTo) {
      trace(entry + '\n');
    }

    [...thing.referenceTo];  // LOCATION OF ERROR, line #178

thing.referenceTo is a Set with a single string value "*" inside as shown by the trace output below.

Output

I wish I could copy & paste from the console in xsbug....

[object Set]
'*'
the-file.js (178) # Break: the-function: cannot coerce undefined to object!

The same thing happens in another place (the case is resched because Object.prototype.toString.call returned string "Set", which was extracted, so obj is sure to be a Set):

case 'Set':
      return actualStringify([...obj], seenObjects);

Just for the record, all of that is well-tested, the exact same code, just a mini-example of our stuff, runs on node.js browser, react-native - and even low.js (on this board).

Works when run in isolation

I tried to run this as an isolated example:

function isString(thing) {
  return typeof thing === 'string';
}

const thing = {
  referenceTo: new Set(['*'])
};

trace(thing.referenceTo + '\n');

for (let entry of thing.referenceTo) {
  trace(entry + '\n');
}

if (
  thing.referenceTo !== undefined &&
  (
    !(thing.referenceTo instanceof Set) ||
    ![...thing.referenceTo].every(type => isString(type))
  )
) {
  throw new Error('Error');
}

but this worked fine.

@lll000111
Copy link
Author

lll000111 commented Mar 8, 2019

PS: I'll keep debugging and if I can't think of anything else create a runnable example to send you.

EDIT: Blocked by #141 in this attempt.

EDIT ²: Unblocked by manifest.json entry `"strip": "[]", but the minimal examples keep working.... :(

@lll000111
Copy link
Author

lll000111 commented Mar 8, 2019

An update: When I replace the [...setObject] by Array.from(setObj) it works. So it seems that there is an issue specifically when the object spread syntax is used. But it only happens in the large project thus far, which I keep shrinking piece by piece to get a small test case. <Sigh>

@lll000111
Copy link
Author

lll000111 commented Mar 9, 2019

Reproducible example

The error is connected to array spread syntax. Everything works if I replace it with Array.from. Also, there have to be two spreads, the first one works.

I ran it on Linux, but I discovered the issue originally on ESP32.

There are two different errors. To discover the first one just uncomment the code marked Error #1.

'use strict';

function isString (thing) {
    return typeof thing === 'string';
}

function ensureRecipeRule (thing) {
    if (thing.referenceTo instanceof Set) {
        [...thing.referenceTo].every(type => isString(type));
    }

    // ERROR #1
    // THE EXACT SAME THING AS ABOVE REPEATED: "callback is no function"
    // if (thing.referenceTo instanceof Set) {
    //     [...thing.referenceTo].every(type => isString(type));
    // }

    // ERROR #2
    // "cannot coerce undefined to object"
    if (thing.idReferenceTo instanceof Set) {
        [...thing.idReferenceTo].every(type => isString(type));
    }
}

trace('Start\n');

[
    {
        referenceTo: new Set(['Person']),
    },
    {
        idReferenceTo: new Set(['Group'])
    }
]
.map(rule => ensureRecipeRule(rule));

trace('End\n');

Result (Error 2):

image

The "callback is no function" error can also be reproduced simply by

function isString (s) {
    return typeof s === 'string';
}

const s1 = new Set('s1');

[...s1].every(isString);
[...s1].every(isString);  // the 2nd call fails

@lll000111 lll000111 changed the title "cannot coerce undefined to object" - but the value is a Set "cannot coerce undefined to object" - Spread into array syntax issues Mar 10, 2019
@lll000111
Copy link
Author

lll000111 commented Mar 10, 2019

Another possibly related example:

Test performed on Linux.

Code

const a1 = [1,2,3];
const a2 = [];

const result = [...a1, ...a2];

Expected Result

[1, 2, 3]

Actual Result

undefined

@phoddie
Copy link
Collaborator

phoddie commented Oct 14, 2020

This was fixed a while back.

@phoddie phoddie added the fixed - please verify Issue has been fixed. Please verify and close. label Oct 14, 2020
@phoddie phoddie closed this as completed Nov 17, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
fixed - please verify Issue has been fixed. Please verify and close.
Projects
None yet
Development

No branches or pull requests

2 participants