Gregorian.info - is it null safe or anything else to consider if used?

I have following code:

var infoShort = Gregorian.info(Time.now(), Time.FORMAT_SHORT);
var day = infoShort.day;
var dayOfWeek = infoShort.day_of_week; // 1 = Sunday, 2 = Monday, ..., 7 = Saturday
var month = infoShort.month; //1 = January, 2= February, ..., 12 = December
var year = infoShort.year;

I get same Invalid value and System error crashes when using the data above... E.g. I see 160 Invalid value crash errors for following line:

var resDays = [
	Rez.Strings.Sun,
	Rez.Strings.Mon,
	Rez.Strings.Tue,
	Rez.Strings.Wed,
	Rez.Strings.Thu,
	Rez.Strings.Fri,
	Rez.Strings.Sat
];
var weekdayName = WatchUi.loadResource(resDays[dayOfWeek - 1]); // <= crashes sometimes

I think assuming that dayOfWeek is in the range [1, 7] as documented here (https://developer.garmin.com/connect-iq/api-docs/Toybox/Time/Gregorian.html) should be save, but why do I get the above exception then?

  • Now I tried following:

    if (!(field instanceof Lang.Number)) {
    	throw new Lang.InvalidValueException("field is no number: " + field);
    }
    if (field < 200) {
    	throw new Lang.InvalidValueException("field < 200");
    }

    And this throw Error Name: Invalid Value in line 5 in the code snipplet... I will try further, but does this mean the text inside InvalidValueException does not work in ERA and that field is < 200? Even if field is < 200, this should be handled by an empty default case in my switch (of course only before I was throwing the exception in line 5 above).

  • Yeah, I went back to my ERA reports and none of the exceptions have associated text :( :( :(. Sorry to waste your time on that. It's too bad Garmin doesn't save/show exception text on ERA reports, because we can't have our nice run-time assertions after all (well we can assert things, but we can't provide any further detailed information about the error, except to check for things that we anticipate in advance.)

    As for that bug, not sure why the switch statement would cause a problem but you could try inserting the following code before line 4 of the snippet and seeing if it crashes:

    switch (field - 200) {
    	default:
    	    System.println("don't expect any problems here");
        	break;
    }

  • I tried now following:

    • extend my code to remove all optimisations
    • one function / calculation per line
    • save everything in intermediate variables

    In addition to check EVERY variable against type / null / range and throwing an exception if something does not fit into what I expect - I will see if I can find something like that...

    PS: maybe following request is interesting for you as well and you want to give it an upvote: link

  • Finally I added a lot of checks like following (same schema for all other values):

    var infoShort = Gregorian.info(Time.now(), Time.FORMAT_SHORT);	
    var month = infoShort.month;
    // ...
    
    // check that all variables to be != null
    if (infoShort == null || day == null || dayOfWeek == null || month == null || year == null || hour == null || min == null) 
    {
    	throw new Lang.InvalidValueException("something is null");
    }
    
    // check all variables to be of the correct type + be in the expected value range
    if (!(month instanceof Lang.Number))
    { 
    	throw new Lang.InvalidValueException("month is no number: " + month); 
    }
    if (month < 1 || month > 12) 
    {
    	throw new Lang.InvalidValueException("month not in range [1, 12]");
    }
    // ...

    And within a day I get following feedback:

    • 1x Invalid value - day_of_week is a number check failed (+ 2x System error at the throw line)
    • 14x Invalid value - month is a number check failed (+3x System error at the throw line)
    • 1x Invalid value - day_of_week range check [1, 7] failed
    • 1x Invalid value - hour range check [0, 23] failed (+ 1x System error at the throw line)

    So mostly I get the information, that the month is not a number - devices and languages are quite mixed, e.g. my own fenix 6x pro with latest firmware 13.10 is also part of the list - but on my watch everything works fine.

    I'm already thinking about making the calculations myself instead of using the Gregorian.info function... Any ideas / suggestions what else I can do?