webidl icon indicating copy to clipboard operation
webidl copied to clipboard

Promise handling algorithms are not very clear about what happens if type conversion fails

Open domenic opened this issue 4 years ago • 6 comments

https://heycam.github.io/webidl/#dfn-perform-steps-once-promise-is-settled

What if the type is Promise<Node> and someone passes Promise.resolve(3)?

I think the best we can do is go down the rejection path? Although that makes using "upon fulfillment" in isolation pretty dangerous for non-any _T_s.

domenic avatar Aug 29 '19 16:08 domenic

I am curious if implementations actually pay attention to the T at all... Do they have counterpart algorithms?

domenic avatar Aug 29 '19 16:08 domenic

Gecko pays attention to the T in the following ways:

  1. IDL parse fails if Promise<T> is the return type of an operation or attribute but T is not exposed in all the globals where the operation or attribute is exposed. There is no corresponding requirement in the spec, as far as I can tell (also for the situation where some type is returned directly, without Promise being involved), but fundamentally it doesn't make sense to have this setup.
  2. Something involving which C++ headers to include in generated binding files. I'm not even convinced that code needs to be there.
  3. The equality operator on types in the IDL parser treats Promise<T> as equal to Promise<U> if and only if T == U. This equality operator is used when coalescing identical unions across IDL files. It could probably ignore the parameter type and just treat app Promise as equal in practice...

There are no other places that are aware of the T in Gecko as far as I can tell.

bzbarsky avatar Aug 29 '19 17:08 bzbarsky

How does respondWith() work in Gecko? Is there a manual type check?

annevk avatar Aug 30 '19 08:08 annevk

In the spec as written, it'll return a rejected promise and the success steps won't be run.

Let's take a look at what APIs take a Promise argument anyway:

This suggests to me that we should run the rejection steps on conversion failure.

Ms2ger avatar Aug 30 '19 08:08 Ms2ger

How does respondWith() work in Gecko? Is there a manual type check?

Yes. See https://searchfox.org/mozilla-central/rev/7088fc958db5935eba24b413b1f16d6ab7bd13ea/dom/serviceworkers/ServiceWorkerEvents.cpp#576,588-591,595-597,605-608 (which checks that the resolution value is an object, then checks that it's a Response.

bzbarsky avatar Aug 30 '19 15:08 bzbarsky

In the spec as written, it'll return a rejected promise and the success steps won't be run.

Ah, I guess because "converting" will throw, and PerformPromiseThen handles it. That makes sense.

This suggests to me that we should run the rejection steps on conversion failure.

Sounds good to me.

domenic avatar Aug 30 '19 17:08 domenic