Mysterious error without stack trace



  • I'm getting weird errors like

    TypeError: Cannot read property 'length' of undefined
    

    And I can't trace them.

    I'm pretty confident this isn't my code, because if there is a syntax error I get a trace. And all my throws are throwing Error objects.

    Is this an issue anyone else is experiencing? Is it just me? Or is it a mystery?



  • I've been having strange undefined errors as well.

    First thing I've found out. It appears there have been some changes to the scoping of variables. Before a variable instantiated like myVar = "test", without a var was globally visible. This no longer seems to be true, but on the up side we now can say global.myVar = "test" and have it work fine everywhere except from the console. This is due the second change I've noticed today.

    The console now seems to happen before the main script (and so before anything we write is defined) instead of after as it had be doing. I'm also seeing some console statements being issued multiple times at random intervals after being entered. It does not seem to happen for a console.log issued at the console but when I started getting strange behavior, I added the following code at the very start of my main module:

    console.log('--')
    if(global.test) console.log('from console', global.test);
    

    From the console, issuing test = "a test" just once results in the conditional being triggered once on the very next tick and then around a half dozen more times on random ticks latter. I was still collecting information when I saw your post.



  • I got an email about a large number of those errors. Something has definitely changed since it has rendered some of my units broken. There will definitely be some code repair when I have the time. Hopefully what JustMonkeyCode has said is true, because I would like the main game to follow the survival training rules, where global is a variable you can define globally into.



  • I can reproduce the same issue by doing following:
    Create module x with one harmless function test() { console.log('hello')}
    In the main module at the very end after all the logic:

    require('x').test();
    

    will throw "undefined" exception on require('x') about half the time for me.
    if I do var moduleX = require('x') in the beginning then
    moduleX.test() works 100% of the time.



  • We have introduced some changes into the runtime engine. Please see details in this article.

    As for the strange errors, I couldn't recreate the errors you described. If you still experience something that you think works incorrectly, please submit a request so that we can together handle this individually.



  • Hmm... I think I found a problem...

    Try this:

    unexisting // or any other variable that doesn't exist
    

    This will print a red [object Object] without stack trace at all, while it actually should throw some error.

    While we're at it, lets do this...

    unexisting.totallyNotExisting.yeahSureItDoesNotExist
    

    Same result...

    Press f12 in a browser (or try any other way to open a console) and try the same code, you get an error instead...



  • And I found another problem... This time its about these errors and its probably my own code. But the error message is to vague about this to let me know what the problem is...

    Here some formatted code

        33: [ function(a) {
            !function() {
                "use strict";
                var b = a("../game/game"), c = a("../game/console"), d = a("lodash");
                return self.onmessage = function(a) {
                    var e, f = a.data, g = {};
                    if (f.user) {
                        try {
                            var h = performance && performance.now ? performance.now() : Date.now(), i = function() {
                                return performance && performance.now ? performance.now() - h : Date.now() - h;
                            };
                            b.runCode(f.userCode, f, g, f.userMemory, c.makeConsole(f.user._id), f.consoleCommands, 1 / 0, i, function() {
                                h = performance && performance.now ? performance.now() : Date.now();
                            }), e = {
                                type: "done"
                            };
                        } catch (a) {
                            e = {
                                type: "error",
                                error: d.isObject(a) && a.stack || a.toString()
                            };
                        }
                        e.intents = g, e.memory = f.userMemory, e.console = {
                            log: c.getMessages(f.user._id),
                            results: c.getCommandResults(f.user._id)
                        }, self.postMessage(e);
                    }
                }, {};
            }();
        }, {
            "../game/console": 35,
            "../game/game": 41,
            lodash: 30
        } ]
    

    Because I can't a certain revision of a gist, the gist may be updated and this code may be replaced so I pasted the code here just to be sure. The code can currently be found in the gist here:

    https://gist.github.com/avdg/2e95caaec63254bcec28#file-engine-js-L4092

    Note that catch (a) { is catching an exception, e is getting assigned with some information, which is a.toString if a is an error object.

    So I decided to simulate the behavior of an error object in the browsers developer console (knowing that my error was very vague).

    So this is an error object

    new Error("Foo bar")
    

    And this is what the code above does with it:

    new Error("Foo bar").toString();
    // "Error: Foo bar"
    

    So there is that vague error coming from 🙂

    This can be fixed by changing the code into this

    new Error("Foo bar").stack
    //"Error: Foo bar
    //    at <anonymous>:2:5
    //    at Object.InjectedScript._evaluateOn (<anonymous>:895:140)
    //    at Object.InjectedScript._evaluateAndWrap (<anonymous>:828:34)
    //    at Object.InjectedScript.evaluate (<anonymous>:694:21)"
    

    Sadly the output of an error object isn't standardized by any ecma standard, so the output may be different in other browsers. But at least the output is way more informative...

    I hope this solves some problems if implemented 🙂



  • Uh nvm... I'm too fast in making conclusions... I need to dig way more into this stuff...



  • Above code was fine... this might be not if the stack doesn't contain a proper error...
    https://gist.github.com/avdg/45aff0191c0b16b1ff31#file-test-js-L19