Unexpected Type Error

I read lots of the old threads about Unexpected Type Error and how Properties.getValue can return null. My problem resembles that, but I still can't figure out what is the problem.

My code is:

function getConfig(key as PropertyKeyType) as PropertyValueType? {
  var val; // this is the line I get the error according to ERA
  try {
    val = Properties.getValue(key);
  } catch (e) {
    logRelease(key + ":" + e.getErrorMessage());
    val = null;
  }
  return val;
}

And this is the error from ERA:

Error Name: Unexpected Type Error
Occurrences: 7
First Occurrence: 2024-01-17
Last Occurrence: 2024-01-22
Devices:
    vívoactive® 4S: 7.80
App Versions: 2.3.1
Languages: pol
Backtrace:
    Config.getConfig:18
    Config.getConfigNumber:93
    MyApp.onStop:122 

So what I know is that the error is in getConfig. And before you point me to the best practices to check for null and type, all that code is in getConfigNumber().
Because the call comes from MyApp.onStop:122, I even know that key = "i" so I believe even the
key + ":" + e.getErrorMessage()
can't be the problem (all 3 are strings)

However I can't understand then what can be the problem in the last line that makes sense:
val = Properties.getValue(key);

the value of the i property is supposed to be a number, but even if it isn't (and that would be taken care of in getConfigNumber) whatever the type of the property is, including null, I can't understand how the above line (or any other line in getConfig() can cause an Unexpected Type Error.

  • "Upcoming Wearable: 12.13" ???!!!???
    Looks like your app crashes on Fenix 8 :) Maybe you should talk to DCRainmaker ;)

  • I don't think he uses cht/chs version :).

  • Well, then BeigingRainmaker :) 

  • I will not add settings for "I", because as I explained above it's being written and read by code, and should not be settable by the user. In new devices it could be written to storage, but since I support devices line epix and fr230 I had to add them to properties.

    What's not clear to me is how Properties.getValue("I") doesn't consistently fail for you. My understanding is that when you use the new API (Properties.getValue() / API >= 2.4.0), the specified property key has to have a corresponding setting, otherwise Properties.InvalidKeyException will be thrown. I thought that it was only the old API (AppBase.getProperty()) that allowed properties to be accessed which don't have a corresponding setting. But of course, devices which support the newer API aren't supposed to use the old API.

    Am I missing something or is the documentation incorrect?

  • Wow! Now I got super confused. My logic has worked for 2 years and 190k downloads.

    Before I re-read the docs on the link I would've been sure it's that in order to make it not throw an exception it has to be existing in properties.xml.

    Let me check something...

  • I see 2 possibilities:

    - you’ve been catching the exception the whole time (but as you say, your logic works)

    or

    - there’s a loophole where setting the value before getting it avoids the exception (but that would seem to contradict the docs for both Properties.getValue and setValue)

    I’ll also note that the core topics page for Persisting Data also insists that the key has to exist in settings for Properties.getValue() and setValue():

    https://developer.garmin.com/connect-iq/core-topics/persisting-data/

  • Possible, I'll check that too.

    3rd option: it might work differently on devices that still have the old apis vs on new devices that don't, but I haven't noticed because of the try/catch and because this feature is only used when you save an activity and continue later, which is not very common, especially with HRM

  • it might work differently on devices that still have the old apis vs on new devices that don't,

    Yeah I think this is it, but I didn’t explicitly mention that bc I was only referring to the code you showed which uses the new API — Properties.getValue(). I would expect the old API to work fine.

    So that would fall under the 1st option: you’ve been catching the exception the whole time (for newer devices obviously)

  • That's not what I meant though. I meant there are 3 groups of devices:

    1. API level [1.0.0 - 2.4.0) (not including 2.4.0) => only can use AppBase.getProperty
    2. API level [2.4.0 - 4.0.0) (not including 4.0.0) => can use both
    3. API level [4.0.0...) => only can use??? Properties.getValue

    What I meant that at the time I wrote and tested the code I used devices in group #2, but maybe devices in group #3 are stricter in when they throw the exception.

  • I tested it with fr965 and fr245 with the store version. They both do what they supposed to do, so I can not say if there's an exception thrown ('cause I catch it) but I can say that the value was both saved and then read back as expected for the property that is only in properties.xml but isn't in settings.xml.