Storage.getValue() when loading casue "System Error" crash

In my data field App, I have haven been using a Storage.getValue("mydataID") call when loading for a long time. And it normally works well. But, recently I do get more and more ERA reports on "System Error" crashes in this very line. I tried putting the line into try/catch statement, but that did not help.

Is this a Garmin bug? Any input on how I can mitigate it?  

  • What else is in that line and the neighboring lines?

  • Not much. The code is in the initialize() function of a class. The object is created in the App getInitialView() function.
    The code:

    try {
    latitudeANDlongitude = Storage.getValue("myLocation");
    }
    catch(ex) {
    latitudeANDlongitude = null;
    }

    As you can see, it's a geo location I'm storing in an array of 2. Which is stored/updated when the App is closing down. Done in the onAppStop() function. In which I btw also, but only few times, have seen a "System Error" ERA crash report in.

  • Yeah, not very suspicious. I also do more or less the same. Sometimes I do see a crash when I save in onStop. But it works for me all the time, and it looks like it works 99.99% of the time for the users too. Someone wrote in the forum that it can be too late to do it in onStop and instead I should do it before (which would mean to save it in compute(). I am not sure if that would remove the crash or just use more battery for thousands of users that never saw a crash...

    As for the getValue: can this device be close to the memory limit at this point of the flow?

  • Are you seeing anything in common in the ERAs such as the device or FW version?  Remember, if you see "x" instances of a crash in ERA, that could be a single user crashing "x" times.

  • thanks for the compute() tip ... think I agree with you on the tradeoffs!

    nope, all I'm storing is an array with 2 values, so storage should not be a problem

  • I do see crashes on multiple devices for sure. Venu, vivoactive and forerunner devices. I have though not noted down the X, so not sure about that. The latest versions with try/catch crashed only once on a forerunner 955 and once on a vivoactive 5. so seem X=1. 

  • Unfortunately, many exceptions in the Garmin SDK are uncatchable, including common ones like Array Out of Bounds and Out of Memory errors. You can find a list of these at the bottom of this page:

    https://developer.garmin.com/connect-iq/monkey-c/exceptions-and-errors/

    That said, this list doesn’t provide much insight into your "System Error." According to the documentation, it’s simply described as “a generic error used by the Toybox APIs for fatal errors.” While this isn’t particularly informative, it does help rule some things out—for example, it likely isn’t an Out of Memory issue, since that has a dedicated error type.

  • I'm not even sure if we can assume that, but you might be right. So probably we only ever see those uncatchabe exceptions in ERA? Did anyone ever see an exception that is documented that a method can throw? Or we'll only see Unhandled Exception in that case?

  • I would expect ERA to display all exceptions that result in an app crash—this includes both uncatchable exceptions and any catchable exceptions that are not handled by the code.

  • Unfortunately, many exceptions in the Garmin SDK are uncatchable, including common ones like Array Out of Bounds and Out of Memory errors.

    To be pedantic [*], those are (fatal) errors, not exceptions. By definition, all exceptions are catchable (in Monkey C, anyway). And significantly, fatal errors and exceptions are not the same thing in Monkey C. (It's not like java, where a failed assert() results in an unchecked exception, for example)

    But yeah, it's very frustrating that so many error conditions in Monkey C or the CIQ API generate fatal errors and not catchable exceptions.

    [*] but actually the terminology is significant, because saying "uncatchable exception" leads to misconceptions/misunderstandings like this:

    "So probably we only ever see those uncatchabe exceptions in ERA? Did anyone ever see an exception that is documented that a method can throw? Or we'll only see Unhandled Exception in that case?"

    No, he doesn't mean a literal exception (as in the app threw an object of type Exception), he's just talking about standard fatal errors that we've all seen in the ERA, ciq_log.yml, and the simulator, like:

    - Invalid Value

    - Array out of Bounds

    - System Error (arguably the most severe of the fatal errors, as it usually means there's a bug in the firmware and there's nothing that can be done on the app end to address it)

    You'll note that when these errors appear in the log, the word "exception" is absent. These errors are generated by Garmin code (somewhere in the API / firmware), we as 3rd-party devs can't directly generate them. We can indirectly generate them by running some code that's already known to trigger them. Iow, I can explicitly throw a ValueOutOfBoundsException whenever I want (even if there's no value that went out of bounds), but I can't generate an "Invalid Value" fatal error on demand (unless I call a certain CIQ API function with a certain arg value that's known to generate the Invalid Value fatal error.)

    On the flipside, when the log says "Unhandled Exception", it literally means that a literal exception was thrown and the app did not catch it. Significantly, it also means the app could've caught the exception if the code had been written differently..