-
Notifications
You must be signed in to change notification settings - Fork 1.3k
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
Should we make native error types distinguishable? #1389
Comments
Error (and the error types) are the only builtins that are not distinguishable via a brand check. It would be appropriate, imo, to directly add some way to cross-realm distinguish NativeErrors from SyntaxErrors, say - at which point structured cloning could use it. One simple change might be, make |
For 1b, why would you use (I.e.: if the input has [[ErrorData]], get its prototype, and if that is one of prototypes of the predefined native error types, use the corresponding prototype in the worker realm. Otherwise fall back to Error.prototype.) |
(It's also worth noting that the stacks proposal will add private state to native errors, and a user mechanism of exposing/brand-checking it - however, the stacks proposal does not currently provide any mechanism of distinguishing between error types) |
@bakkot fair point; I don't really know what principle would help choose between |
@ljharb I don't understand what this means:
since SyntaxErrors are NativeErrors. In particular the main question of this thread isn't really about brand checking for errors in general; that's already in the spec via [[ErrorData]], and may eventually be expanded (although I'm not holding my breath) if the stacks proposal ever advances. The question is about whether "being a TypeError" vs. "being a SyntaxError" vs. "being an EvalError" is just a consequence of public properties of error instances, or is a more intrinsic part of their identity. |
oh sorry, that's a mistype - RangeErrors from SyntaxErrors, then :-)
Indeed - my personal feeling is that since they're separate constructors, they have thus intrinsically different identities, and it's useful to be able to distinguish them - both in the same realm, and across them via serialization. |
RangeErrors are also NativeErrors... |
To avoid confusion I'll restate my entire sentence, with a correction:
|
My preference is to avoid adding brands unnecessarily, and I don't see a good reason for user code to need an unforgeable way to distinguish between different types of errors. So my preference would be for options 1a or 1b (I think 1b or a variant would be more useful and less surprising, but that's a bit outside the scope of this issue). @domenic, suppose that WHATWG did go with 1b and then later TC39 added some way to allow JS code to distinguish between error types (though like I say I'd prefer that we not do that). Do you think it would be feasible to change the structured clone algorithm to match? Do you think it would be a problem if it didn't match? |
Respectively: yes, and no problem. In more detail: In general we've found on the web very little code cares about error typing, i.e. we are often able to change error types without compat risk. I'd be especially surprised if anyone managed to write code that changes the "type" of an error at runtime by mutating And, even if for some bizarre reason it turns out to be web-incompatible to update and match, I'd see that as only a minor edge-case wart, not a big deal. |
how about the constructors set [[ErrorData]] to the current constructor? RangeErrors would have [[ErrorData]] === %RangeError% and etc |
@devsnek currently nothing is set in that slot; however, the stacks proposal needs a slot to store the stack data. It's fine if [[ErrorData]] is repurposed, but that means the stacks proposal would need to add a second slot (which also might be fine; just pointing it out) |
It feels broken to me to copy the message without the error type, or let the error type be strangely spoofed; I'm not sure what benefit that would have to users. I like option 2. Note that the WebAssembly JS API also includes NativeErrors; these should probably be treated similarly. |
The way I see it is that, if the spec does not distinguish between |
@bakkot that reasoning seems technically sound for the example given, but I think littledan might be pointing at a different kind of spooky “spoofing”:
|
Sure. That's a good argument for switching on |
Thanks all for the help on this. Over in whatwg/html#4268 I've recommended that we switch on |
In whatwg/html#5140 I am suggesting we change from |
For background, see whatwg/html#4268. On the web, we'd like to make cloning of errors between realms possible (via structured clone). There's a slight wrinkle though, which is that unlike other cloneable types which have an individual brand, all NativeError types share the [[ErrorData]] brand. I'm opening this issue to get a TC39 discussion started on what to do.
To start, note that if you do
the structured serialization algorithm looks at
map
, finds its [[MapData]] brand, and deserializes inside the worker using the worker'sMap.prototype
. The question is, what should happen if you door if you do
?
I see two paths:
Decide that error types being non-distinguishable is a feature. It's intended behavior that
t2
is indistinguishable fromnew SyntaxError()
. Native errors have no private state; everything interesting about them is derived from their public properties.Error.prototype
in the worker realm. (I.e., clones are alwaysError
, never anything more specific.).name
property, and if that is one of the predefined native error types, use the corresponding prototype in the worker realm. Otherwise fall back toError.prototype
.Decide that it should be possible to distinguish error types.
t1
andt2
would deserialize using the worker realm'sTypeError.prototype
.Thoughts welcome!
The text was updated successfully, but these errors were encountered: