if is not catching... nor does try-catch...

Posted on
  • In handling of optional parameter in constructor I got a bit lost... and still am... ?-(

    This is the original code, and I do not know what is wrong with it...

    // goal: pass an optional C(onfig) object to update the C(onfig) in prototype
    
    function Clazz(C) {
      if (C) for (var v in C) this.C[v] = C[v];
    }
    
    Clazz.prototype.C = 
    { c: 100
    };
    
    var aClazz  = new Clazz();
    console.log("aClazz.C.C =",aClazz.C.C);
    

    Running this code I get following console output:

     1v70 Copyright 2014 G.Williams
    >echo(0);
    aClazz.C.C = 100
    =undefined
    Uncaught Error: FOR loop can only iterate over Arrays, Strings or Objects, not undefined
     at line 2 col 43
      if (C) for (var v in C) this.C[v] = C[v];
                                               ^
    > 
    

    I had expected that by design the if would have taken care of an undefined parameter variable C and skip the for-loop. The for-loop should only execute when is C defined.

    Invoking constructor with empty object works:

    var aClazz  = new Clazz({});
    

    logs:

     1v70 Copyright 2014 G.Williams
    >echo(0);
    aClazz.C.C = 100
    =undefined
    >
    

    Invoking constructor with changing object works:

    var aClazz  = new Clazz({ C:50 });
    

    logs:

     1v70 Copyright 2014 G.Williams
    >echo(0);
    aClazz.C.C = 50
    =undefined
    >
    

    Next step I tried was for loop with curly braces - to no avail:

      if (C) for (var v in C) { this.C[v] = C[v]; }
    

    Next step I tried if with curly braces - but not the for loop - and it worked... (update: ...hold your horses, this was not the last snag... keep on reading!)

      if (C) { for (var v in C) this.C[v] = C[v]; }
    

    Sure, I always recommend to use curly braces. Before I though added them, I tried the avenue of try-catch to find out what is going on. It seemed to me odd that the reporting of the error was actually after execution of all the code and the error did not stop the code from executing... (as it would have done in a browser).

    function Clazz(C) {
        if (C) for (var v in C) this.C[v] = C[v];
    }
    
    Clazz.prototype.C = 
    { C: 100 };
    
    try {
      var aClazz  = new Clazz();
      console.log("Clazz() constructor passed");
    } catch(x) {
      console.log("exception in Clazz() constructor:",x);
    }
    console.log("aClazz.C.C =",aClazz.C.C);
    

    logs:

     1v70 Copyright 2014 G.Williams
    >echo(0);
    Clazz() constructor passed
    aClazz.C.C = 100
    =undefined
    Uncaught Error: FOR loop can only iterate over Arrays, Strings or Objects, not undefined
     at line 2 col 45
        if (C) for (var v in C) this.C[v] = C[v];
                                                 ^
    > 
    

    Surprisingly, the try-catch does not catch the error... it lets the faulty expression to pass... so I wrapped the actually expression in the constructor into a try-catch block...

    function Clazz(C) { // --------------------------
      try {
        if (C) for (var v in C) this.C[v] = C[v];
        console.log("Clazz() constructor passed");
      } catch(x) {
        console.log("exception in Clazz() constructor:",x);
      }
    }
    
    Clazz.prototype.C = 
    { C: 100 };
    
    var aClazz  = new Clazz();
    console.log("aClazz.C.C =",aClazz.C.C);
    

    with the same puzzling result...

    So I'm asking:

    • What is going on here?
    • Why is the if not catching when not provided with curly braces?
    • Why it the try-catch not catching the error
    • Why is the error reported at the end of all reporting... (console output)

    I had tried to use try-catch block in a different project,... and it did not work there either. Because int that project it was precaution and the anticipated possible error did not show (yet), so I ignored 'to go to the bottom of it'.

  • The if (C) {...}-thing still gives me annoying grieve,... I thought the added curly braces would have solved the issue for good...

     1v70 Copyright 2014 G.Williams
    >echo(0);
    Uncaught Error: FOR loop can only iterate over Arrays, Strings or Objects, not undefined
     at line 1 col 288
    ...or(var v in C)this.C[v]=C[v]}
                                   ^
    

    Related to this code (line 10 in constructor), coming from the (again) working space-only-minified sandbox modules folder. (Had to re-enable some minification option after getting unexplicable out of memory error - see http://forum.espruino.com/comments/11900960/).

    // ACD pins for X-, X+, Y-, Y+, optional - but one - callbacks, optional C(onfig) 
    function TOUCHR(xn,xp,yn,yp,onDownCB,onTrackCB,onUpCB,onEscCB,C) {
      this.xn = xn; this.xp = xp; this.yn = yn; this.yp = yp;
      this.cbs = [[onDownCB,onTrackCB,onUpCB,onEscCB]]; 
      this.w = null; this.te = 0; this.upCnt = 0; this.up = true;
      this.xr = this.xrr = this.yr = this.yrr = -1;
      this.x = this.x0 = this.x1 = -1;
      this.y = this.y0 = this.y1 = -1;
      this.t = this.t0 = this.t1 =  0;
      if (C) { for (var v in C) { this.C[v] = C[v]; } }
    }
    

    The constructor is invoked with undefined for C.

    The minification messes with the code to the point where the execution and block nesting becomes broken... Why would I say so: Adding/removing some code further down in the module made the error flip-flop...

    Interestingly, when I put a console.log() in the if-(then) block, it 'tricks' the minification and - miraculously (for me) - works:

      if (C) { console.log("C:",C); for (var v in C) { this.C[v] = C[v]; } }
    

    @Gordon, since you know your code like your own pockets, I'm sure you have a nice explanation - and may be - even a remedy top of your head... ;-)

    The stuff seems to be related to what @DaveNI experienced in Minified Code Producing Error - Solved at http://forum.espruino.com/conversations/257029/

  • So are you describing two different errors?

    The first issue happens with unminified code outside of a module?

  • Yes, two different 'errors' - may be actually 3:

    The if-issue - covering a double issue - is now clear (I guess): it is the combination of minification and Espruino's interpreter and the 'common' JavaScript syntax and Espruino's interpreter.

    Latter could be fixed by adding curly braces, when then get removed by minification, because minification detects that there is only one statement in the block(s) and removes the curly braces, which get syntax and interpreter at odds again.

    The second one is the try-catch thing... it is somehow not working the way I'm used to... I expected it would catch this error: for loop can only iterate over .... and object's properties -and not over undefined object C. (try { var C = undefined; for (var v in C).... } catch(x) {.... }).
    I looked at the try catch test cases in github as examples... but somehow it does not work in this case.

  • Would it be ok if you posted some separate issues on GitHub, ideally with a simple section of code for each?

    I'm a bit busy right now with the new KickStarter so I don't want to forget about them - If they're on the issue tracker I'll be able to pick them up easily and fix them when I have a few minutes.

  • @Gordon, np, well understood... I'm excited about he Pico! Congrats: 2 days and 50%, trippled+ since I noticed yesterday! (of course, I'm 8 hrs time zone late...).

    Issue will not get forgotten... I will have to go back to that particular code anyway. In the meantime I did some work on ILI9341 module...

  • Thanks! :)

  • Just to say I just fixed for (var i in undefined) for you. It'll be in 1v71.

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

if is not catching... nor does try-catch...

Posted by Avatar for allObjects @allObjects

Actions