Error I cant deal with

Hye everyone,

I have an error I can't deal with and I don't understand.

Its from a watchface, the weird thing is it works on many models, It works on some Fenix 5+ but stuck on some other Fenix 5+...

I know the about the Iphone bug for date picker but in the log file the error is not due to that, here is the lines where the error occurs: 

			if (HasFC) { // FLOOR
				dataW = 30/ActM.getInfo().floorsClimbedGoal.toFloat()*ActM.getInfo().floorsClimbed.toFloat();
				if(dataW > 30) {dataW = 30;}
				dc.drawRectangle(x, gH-37+Xs+y, dataW.toNumber(), 1);
			}

where HasFC =  (ActM.getInfo() has :floorsClimbed);

I hope you can explain me why this happens.

Have a great day.

  • Error : invalid value 

    Details: Failed invoking <symbol>

  • put in some println calls to see if you can determine the line it occured on.

  • The problem is That it works well on sim, well on my watch, well on some f5+ but not on some f5+... 

  • If you know which user it is failing for and they are willing to load a custom debug build, then I would suggest changing the code as follows, so you can isolate the problem. (There's only a few places it can reasonably fail, assuming that any device which has floorsClimbed also has floorsClimbedGoal).

    if (HasFC) { // FLOOR
        var activityMonitorInfo = actM.getInfo();
        
        if (activityMonitorInfo.floorsClimbedGoal == null) {
            System.println("activityMonitorInfo.floorsClimbedGoal == null");
        } else if (activityMonitorInfo.floorsClimbed == null) {
            System.println("activityMonitorInfo.floorsClimbed == null");
        } else {
            dataW = 30/activityMonitorInfo.floorsClimbedGoal.toFloat()*activityMonitorInfo.floorsClimbed.toFloat();
            
    	    if(dataW > 30) {
    	        dataW = 30;
    	    }
    	    
    	    dc.drawRectangle(x, gH-37+Xs+y, dataW.toNumber(), 1);
        }
    }

    As a matter of fact, the documentation for activityMonitorInfo (and history) recommends doing null checks in any case. Even though it may not seem intuitive or logical for a given function to return 0, you should follow that kind of recommendation unless you're absolutely sure it won't be a problem.

    developer.garmin.com/.../Info.html

  • It could be that activity tracking is off on some of the devices.  I'd add a check for Sys.getDeviceSettings().activityTrackingOn

  • Good call. I should've added a check for whether actM.getInfo() returns null, although I'm not sure getInfo() is supposed to return null or whether the fields within are null, in that case.

    Anyway, in the above debug example, it would crash on a line that points to the (first) problem in any case.

    Of course, assuming you have enough memory/power budget for the code, it doesn't hurt to do all the checks. Or just do the activityTrackingOn check as you suggested.

    EDIT: I'm seeing in the source code for a popular watchface that null checks are done for the fields within ActivityMonitor.Info and not the object itself, so it's probably safe to say that the object returned by ActivityMonitor.getInfo() is never null.

    I suppose I wish this were the kind of thing that actually was documented explicitly, so it would be easier to write the leanest code possible without testing the exact scenario (or worrying that the behaviour could change.)

  • the safest check is activityTrackerOn, because null doesn't always show that it's off.  For example, if it is on and you did some steps and then turn it off, there will be steps but they won't change.  I just don't do anything with ActMon if it's off in my apps.

  • Ouch - I've just had to add checks to all my code using activityMonitorInfo values now! I wasn't checking any of them for null before. Maybe I'm just lucky no one reported a crash due to it.

    Although I've just looked at the open source for the Crystal watchface - it looks like it doesn't seem to do any checks for null either on values from activityMonitorInfo.

    One thing I would be worried about in the code above is whether floorsClimbedGoal could be 0 - in which case you'd end up with a divide by zero …

    Testing that, if I run this code:

    var dataW = 30/(0).toFloat()*(0).toFloat();
    if(dataW > 30) {dataW = 30;}

    Then I get this error on the first line:

    Failed invoking <symbol>
    Invalid Value

  • hye!

    ok so I've tryed  advices, still the same error,  check, again the same error,

    I have a data field which can show either daily steps (it works) or small data fitness, this one break and according to the log at floor climbed ... even if before there is the activityTrackerOn check and even if it is null check...