TL;DR - How can I determine which anonymous function a thrown error came from?
See: https://jsfiddle.net/xhj1Ld3n/
Which works in chrome, but not firefox
Long version:
I am making a JS game that allows players to write dynamic Javascript. The player-provided code is put into a Function()
which is executed.
The problem is that if the player makes a typo (which causes an error to be thrown) it's hard to get 2 pieces of information which I want to present to the player:
Which line number in the player-provided function triggered the error
Which player-provided function triggered the error (the player can provide more than 1)
I solved number 1 by doing:
window.onerror = function(message, source, lineno, colno, error) {
// get line number from lineno
}
This seemed like the easiest way to get the line number from an error without doing browser-specific parsing of error.stack
.
Now I'm trying to figure out how to determine which player-provided function it came from.
Initially I tried giving the player provided functions names with Object.defineProperty
so that I could then parse out the name from the error stack:
Object.defineProperty(playerFn, "name", {value: "playerFn1"});
However, while this works in Chrome:
ReferenceError: x is not defined
at playerFn1 (eval at executePlayerCode (game.js:370), <anonymous>:22:1)
...
in Firefox it looks like this:
ReferenceError: x is not defined
anonymous http://localhost:8000/js/game.js line 370 > Function:22
...
So it looks like changing the Function
name only has an effect on the error stack in Chrome, not Firefox.
My question is... is there a somewhat portable method I can use to identify which Function()
a given thrown error is referring to?
I tried wrapping the player-provided code with a try/catch that injects additional context into the error before re-throwing, but in Chrome this corrupts the line number in window.error
with the rethrow line number, not the original throw line number.