tc39 / proposal-error-stacks

ECMAScript Proposal, specs, and reference implementation for Error.prototype.stack / System.getStack
https://tc39.github.io/proposal-error-stacks/
MIT License
170 stars 13 forks source link

What should happen the .stack getter is invoked on non-error instances #3

Closed evilpie closed 7 years ago

evilpie commented 8 years ago

There is some evidence that having Error#stack throw for non error instances is web incompatible.

This came up while I was changing Error.prototype to an ordinary object in Firefox bug 1213341. It looks like v8 is generally not affected by this because they define stack on every new error instance.

ljharb commented 8 years ago

In https://github.com/ljharb/proposal-error-stacks#compatibility (the markdown was broken until just a moment ago), I document some of the current state of things.

Safari has a data property (which thus never throws) and v8/spidermonkey use getters - Firefox's throws but v8's returns undefined.

To me, this seems like cross-browser code can not rely on .stack from that SO code - since it will do one of throw, return undefined, or return the stack trace - which tells me that we can do whatever we want here.

Thoughts?

evilpie commented 8 years ago

Firefox's throws

Actually the way it's implemented in Firefox right now, it almost never throws for "real world" uses. Error.prototype.stack doesn't throw, because Error.prototype is an error instance. Object.create(Error.prototype).stack doesn't throw, because we manually walk the [[Prototype]] chain and find a valid error object. I believe this was introduced when we switched from an instance property to the prototype getter to prevent exactly this kind of error. Yes it's rather unfortunate and I would like to simplify the implementation.

ljharb commented 8 years ago

we manually walk the [[Prototype]] chain and find a valid error object

this approach would work in the spec too, to find Error.prototype, even if it was an ordinary object - but I suspect we don't want that logic in the spec.

erights commented 7 years ago

We could have the Error.prototype.stack getter not throw but have System.getStack throw. There was no strong reason for the getter and System.getStack to have precisely the same behavior; it was just that there was no reason not to. Now there is.

ljharb commented 7 years ago

That sounds perfectly reasonable

ljharb commented 7 years ago

@erights in the case where the getter is .called on a non-Error object, what should it return?

erights commented 7 years ago

undefined

evilpie commented 7 years ago

Wait, how did you decide on undefined? I cited multiple examples that result in "" (empty string), i.e. the stackoverflow question.

ljharb commented 7 years ago

@evilpie in that SO code I see a lot of || '' which seems like it'd work with undefined, but it's a long post so it's hard to distill out the compat details.

Can you elaborate on why undefined wouldn't be compatible, or why returning the empty string would be better?