Skip to content
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

Uncaught TypeError: Function.prototype.toString is not generic for inspecting variables #61

Open
jmvtrinidad opened this issue Dec 1, 2016 · 2 comments

Comments

@jmvtrinidad
Copy link
Contributor

jmvtrinidad commented Dec 1, 2016

Hi,
Whenever I inspect computedVariables error shows Uncaught TypeError: Function.prototype.toString is not generic. Any Idea @ntrrgc.
ko-es5-error

From the meantime, I inserted this code as checking.

var isToStringAllowed = true;
try{
    coercedObj.toString()
} catch(e) {
    isToStringAllowed = false
}
if (isToStringAllowed && coercedObj !== Window.prototype && 'toString' in coercedObj
  && coercedObj.toString() === '[object Window]') {
...
@ntrrgc
Copy link
Contributor

ntrrgc commented Dec 1, 2016

First, I want to explain why such an error would be thrown. Basic JavaScript data types all have a method named toString(). It's important to note that each method pertains to one class (Function, String, Number or Object) and only handles their kind.

So this works:

> Function.prototype.toString.call(function myFunction() {})
"function myFunction() {}"

But this doesn't:

> Function.prototype.toString.call({})
Uncaught TypeError: Function.prototype.toString is not generic(…)

How could this happen when not forcing it with call, like in the code above? (thing.toString()) Well, through somewhat strange inheritance or method assignment:

> var a = {};
> a.toString = Function.prototype.toString;
> a.toString()
Uncaught TypeError: Function.prototype.toString is not generic(…)

You may want to check why you have objects with a broken toString() method.

In any case, we'd rather not have the debugger break on any object no matter how broken its toString() method is, so running it inside a try/catch is indeed a good idea.

Instead of calling toString() twice, with only the first call guarded, I suggest replacing it by a safe function that cannot fail:

function safeToString(thing) {
    try {
        return thing.toString();
    } catch (e) {
        return "[toString failed]";
    }
}
...

if (coercedObj !== Window.prototype && "toString" in coercedObj
  && safeToString(coercedObj) == "[object Window]") { ...

@jmvtrinidad
Copy link
Contributor Author

Thanks for the good catch there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants