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.

  • Anyway the exception I was originally talking about a few days ago is about a property that does have a setting as well, so that's a totally different issue.

  • If all properties should be used in settings, why there is no build error or at least a warning?

    I don't use 'hidden' properties and minimal sdk ver. is 2.4 and still can see such errors.

  • TL;DR I think you were right the first time and the only requirement for Properties.getValue()/setValue() is that the key exists in app properties, not settings. There's a discrepancy in the docs, and the text of the exception that the doc claims is thrown when a key is missing from settings is quite clear:

    Exception: Key does not exist in Application Properties

    Anyway the exception I was originally talking about a few days ago is about a property that does have a setting as well, so that's a totally different issue.

    Sure, I was just curious.

    For what it's worth I added the following code to a simple data field's AppBase.initialize():

    var val = Properties.getValue("badKey");
    System.println(val);


    I ran it on a simulated fr965 several ways:

    - With badKey present in properties as a string, with no corresponding setting

    The string was printed to the console

    - With badKey not present in properties/settings (but application has 0 properties defined in resources):

    Error: Unexpected Type Error
    Details: Failed invoking <symbol>

    - With badKey not present in properties/settings (but application has more than 0 properties defined in resources):

    The following exception was thrown:

    Error: Unhandled Exception
    Exception: Key does not exist in Application Properties

    This was super interesting to me so I changed the code as follows:

    try {
      var val = Properties.getValue("badKey");
      System.println(val);
    } catch (e) {
       System.println("e instanceof Properties.InvalidKeyException: " + e instanceof Properties.InvalidKeyException);
    }

    Now it prints:
    e instanceof Properties.InvalidKeyException: true

    The most interesting about this is that the getValue() docs claim:

    But the setValue docs say:

    (I missed the discrepancy when I previously looked at this.)

    And ofc, core topics > persisting data says this about both getValue() and setValue():

    "Property values must be defined in the application settings xml. If a key that is not present in application settings is passed to Properties.getValue(), an exception will be thrown"

    So idk if the getValue() and core topics docs are wrong.

    I don't really want to do this, but I guess I'm gonna file a bug report.

    If all properties should be used in settings, why there is no build error or at least a warning?

    Yeah, that's a good point. There's def a build error for in the inverse situation, where a setting uses a key that doesn't exist in properties.

    But then again, if this is only a problem that affects the new API and not the old API, it can't be a build error unless you set min API level >= 2.4.0. You're still right that it could be a warning, if it were actually the case that all properties should be used in settings (for >= 2.4.0)

  • - With badKey not present in properties/settings (but application has 0 properties defined in resources):

    Error: Unexpected Type Error
    Details: Failed invoking <symbol>

    This one is kinda interesting to me as that's the error you're getting, but clearly it doesn't make any sense in the context of your app.

    Maybe it has something to do with properties/settings being reset, as mentioned earlier?

  • Regarding the min api level vs compiler warning: IMHO they can do better. While it is trivial to base such warning on the min api level, it is not much more difficult to also base it on the minimum connectIqVersion on the partNumber it is compiling for. Though it's a bit more difficult if (and we don't know this) there are 3 different groups of devices based on the api level (I'm thinking especially those that still have the old apis but also already have the new ones)

  • IMHO they can do better

    evergreen comment

  • Though it's a bit more difficult if (and we don't know this) there are 3 different groups of devices based on the api level (I'm thinking especially those that still have the old apis but also already have the new ones)

    idk it seems insane to me to change the behavior of the new api based on the availability of the old api, but again this is garmin we're talking about

  • I'm thinking especially those that still have the old apis but also already have the new ones)

    Has Garmin actually removed the old API from any device? Last time this came up (in a bug report about the deprecation warning), the CIQ team expressed frustration that devs keep using the old API, which prevents them from actually removing it.

    For what it's worth, I can call AppBase.getProperty() on a simulated fr965 and it doesn't crash.

    Again, I don't think they would change the behavior of new code based on whether old code is still around.

  • I'm not even sure if this claim is correct or it's a misinterpretation of the analysis of the iq files - similar to how they don't fix the bug that warns us when we're using the old apis, even if it's only used on the old devices that ONLY have the old apis...

    WARNING: fr230: source/Config.mc:42,2: '$.Toybox.Application.AppBase.getProperty' is deprecated.