stefanpenner / es6-promise

A polyfill for ES6-style Promises
MIT License
7.3k stars 593 forks source link

Accessing `then` on a `function` or `object` throws within the `getThen` helper #346

Open BairDev opened 5 years ago

BairDev commented 5 years ago

Here we try to get the then method from an undefined thing called promise.

https://github.com/stefanpenner/es6-promise/blob/314e4831d5a0a85edcb084444ce089c16afdcbe2/lib/es6-promise/-internal.js#L33

I think it should look like Promise.then, since Promise is defined.

I've seen this in IE11 (no Promise there) and we always run into the catch branch. I'v thought that this is not its intention.

stefanpenner commented 5 years ago

promise is defined as the argument: https://github.com/stefanpenner/es6-promise/blob/314e4831d5a0a85edcb084444ce089c16afdcbe2/lib/es6-promise/-internal.js#L31

And there is no Promise.then.

stefanpenner commented 5 years ago

We can likely fast path that codepath with some extra checks. Will investigate in the AM

hilbix commented 4 years ago

If this is an issue at the "then"able check on resolve(value), then can it be, that IE11 in fact has some issues with objectOrFunction returning true where it shoudn't (i.E. when value===void 0)?

https://github.com/stefanpenner/es6-promise/blob/314e4831d5a0a85edcb084444ce089c16afdcbe2/lib/es6-promise/-internal.js#L106-L107

Usually value.then (which is returned by getThen(value)) should give undefined and not throw. Because throwing makes the Promise to recject.

stefanpenner commented 4 years ago

@hilbix do you have a scenario in mind where that would occur?

hilbix commented 4 years ago

@stefanpenner Not particular. This is what I see in the code, not by direct observation. Sorry. Perhaps I was't clear enough to express my thoughts, so 2nd try here ;)

The OP writes, that promise is undefined in getThen(). AFAICS the only code which calls getThen() is the snippet:

handleMaybeThenable(promise, value, getThen(value));

However this is guarded by objectOrFunction(value), hence this must return true on the given value:

https://github.com/stefanpenner/es6-promise/blob/314e4831d5a0a85edcb084444ce089c16afdcbe2/lib/es6-promise/utils.js#L1-L4

Even if null is not void 0 and redefined to something weird, the typeof x should not give object nor function for non-objects and non-functions. However if it is an object or function, an access to .then should not throw, either.

Well, yes, we can create objects and functions which do not allow access to the property .then. But this then is by purpose, read, perhaps it's better when it throws!

So what's left?

The only thing I can think of is, that, perhaps, the OP returned some IE11-special object from the Promise, which gives either function or object on typeof, but IE11 disallows access to property .then.

In that case, the OP should, please, tell us which type of object the promise was, because this is very esoteric, so hard to find out.

Read: There definitively is too few information to be able to solve this riddle here.

stefanpenner commented 4 years ago

the OP returned some IE11-special object

@hilbix I agree with your analysis.