Strange error while reading settings for datafield

Dear fellows;

Sometimes I get strange errors via ERA for my datafields which I cannot understand or do something against. 
Here is one of them:

Line 635 in View is reading the variable rpmSwap from settings:

        isColored = Application.Properties.getValue("_isColored");
        isEnvelope = Application.Properties.getValue("_isEnvelope");
        isPower = Application.Properties.getValue("_isPower");
        caloriesToggle = Application.Properties.getValue("_caloriesToggle");
        rpmSwap = Application.Properties.getValue("_rpmSwap");  // LINE 635 OF ERROR
        isLaps = Application.Properties.getValue("_isLaps");
        isPozone7 = Application.Properties.getValue("_isPozone7");
        cadMax = Application.Properties.getValue("_cadMax");
        hrMax = Application.Properties.getValue("_hrMax");
        gradDigits = Application.Properties.getValue("_gradDigits");

_rpmSwap in settings is Boolean - it can only be true or false - and it is present in settings.XML

		<property id="_isPower" type="boolean">true</property>
		<property id="_caloriesToggle" type="boolean">true</property>
		<property id="_rpmSwap" type="boolean">false</property>
		<property id="_isLaps" type="boolean">true</property>
		<property id="_isPozone7" type="boolean">false</property>

As I said before - such errors happen from time to time - not regularly.
( I myself use this datafield, too - and I never experienced that error)

I think - I have to live with it - or?

  • Were both _rpmSwap and all the other properties you read before line 635 added to the app in the same version? Or is it possible that all the previous propeties were added let's say in version 1 but _rpmSwap was added in version 2? Can it be that the problem is that for a user who installed the app in version 1 and then upgraded to version 2 the _rpmSwap is missing from the properties, that's why it crashes?

  • no, because he gets the exception on the getValue line, so it would fail the same way if you used that pattern.

  • When I read settings/properties, I always have the getValue() inside a try/catch.  If for some reason the key can't be read (settings reset?), you'll get the error you see if you don't catch it.  In catch, I return a default value for the property so no app crash.

    As it only happened once, per ERA, it's far from common with your app.

  • I know the guy that first wrote readKeyInt, in fact, he's stilling in my chair!

    Since that was first posted, I've changed it a bit as I use getValue() (with try/catch) for devices with Application.Properties, but still do the same check for the type and can return a default value if things go wrong.

  • Or is it possible that all the previous propeties were added let's say in version 1 but _rpmSwap was added in version 2?

    Yes, indeed this value was added - but some versions ago.

    I always have the getValue() inside a try/catch.

    Ahh - I thought try/catch does not work for that kind of exception!
    Does it mean, I have to implement a try/catch for every getValue() ?
    (much of code…)

  • I have my getValue calls in common functions, like in readKeyInt, so doing this adds very little extra to my apps.  Only one try/catch per common function.

    When I do a new app, settings are often one of the last things I do, So in development, getValue() always causes an exception that I catch and default.

    This also prevents an app crash if for some leason a setting gets lost or reset.

    And remember, even though something was added to an old version, a user may not have updated the app since that old version so the change is "today".

  • Another note, is I only use Application.Properties for things that need to be there - properties with associated settings.

    For everything else, I use Application.Storage.  And if a key doesn't exist in Storage, there is no exception, just that a null is returned for getValue.

  • Thanks all for your help!

    I will follow your advice and add try/catch.

  • I've built a function for reading all the properties.
    Works like a charm!
    Thanks to all!

        function readProperty(read, erresult) {
            //System.println("Read: " + read);
            try {
                result = Application.Properties.getValue(read);
            } catch (e) {
                result = erresult;    
            }
            return result;   
            //System.println("Result: " + result); 
        }
    

    Call:

            //rpmSwap = Application.Properties.getValue("_rpmSwap");
            rpmSwap = readProperty("_rpmSwap", false);