UserProfile.getHeartRateZones crash when accessing return array

As you can see I get a crash when accessing the heart rate zones - this happens with a test app on my own device and it happens very rarely - my WF ran for a day while displaying the heartrate as complication...

Any ideas why this can happen?

1) Is it possible that UserProfile.getHeartRateZones may return null at some point?

2) can I rely on the docs regarding function return types like e.g. the on here: https://developer.garmin.com/connect-iq/api-docs/Toybox/UserProfile.html#getHeartRateZones-instance_function

It says the function can't return null - is that a guarantee?

  • How do you know? Trial and error? I use strictMode and the docs say, it can't be null, also the IDE help (I'm unsure if it comes from prettier or monkeyc though) says the same (I assume it's just from prettier using the SDK docs though).

    Actually I removed some null checks because the IDE told me it's impossible that the return value can be null - the above code was one place where I removed the null check...

    And can this even change at runtime while using the same watchface without ever making any changes inside my watch? Because this is what happened today. It just crashes at a random time during the day while not doing anything at all, for sure no settings changes on the watch nor in the phone app...

  • So it reproduces on your watch? That's good, then you can try it by adding back the null check (and log when it is null or make it somehow apparent on the display)

    From your code it look like the only possibility that it's null. I do have 1 DF that uses this function but I can't look at it's code until tomorrow

  • I just added it back and will see if it fixes the issue... Still, when I want to optimise my code and get rid of unnecessary lines, this is really a big issue if you can't rely one the IDE or SDK docs...

  • I agree, but it's a known issue that the documentation is sometimes buggy

  • https://forums.garmin.com/developer/connect-iq/i/bug-reports/error-bug-getheartratezones

    It says the function can't return null - is that a guarantee?

    It should be, especially if the type check information matches the documentation (and it generally does.)

    But it could be that there’s either a bug in the documentation or the implementation.

  • After adding a null check in line 82 directly above the exception line before the first access to the zones variable and I still get this exception... Any ideas what may cause this?

  • It's an unhandled exception. Add a try catch and log it, maybe it'll give some idea

  • If data[4] is null, then comparing it to value (a Number) with value >= data[4] will cause an exception, because those two types are incompatible with > and <.

    Yeah, I know the API doc says that the result has to be an array of numbers (and doesn't mention that the elements can be null), but I wonder what happens if you call getHeartRateZones() for a sport type for which the user hasn't set up zones. (I should really try this on a real device lol)

    I can think of 3 possibilities:

    1) getHeartRateZones() returns null (ofc the API doc doesn't specify this)

    2) getHeartRateZones() returns an array of nulls (again, not specified)

    3) getHeartRateZones() returns the values for HR_ZONE_SPORT_GENERIC instead

    I guess it's also possible that it could return an empty array, but that would also not be specified by the API doc. Besides, if that were the case, your array size check would avoid a crash. (And if you didn't have the size check, the ensuing out of bounds access would be a system error and not an exception - at least that condition is a system error the last time I checked, which was admittedly years ago.)

    3) is the only possibility where your crash doesn't make any sense at all, so maybe it has to be one of the others. I would log zones before the crash.

    I also wonder if 3) is actually the case, but there's also an edge case where the generic zones are all null. Normally this shouldn't happen - I think during device setup, Connect asks for your age and sets default zones appropriately. But what if a user skips device setup? (Then again iirc devices are usually set up with a default age out of the box, too)

    Whatever the case may be, it seems that the API docs need to be updated.

  • catch (e instanceof Lang.Exception)
    {
        System.println("HR Exception");
        System.println("Message: " + e.getErrorMessage());
        //e.printStackTrace();
    }

    Any idea why printStackTrace simply crashes the watchface when throwing an exception manually like throw new Lang.Exception();?

    Yeah, I know the API doc says that the result has to be an array of numbers (and doesn't mention that the elements can be null), but I wonder what happens if you call getHeartRateZones() for a sport type for which the user hasn't set up zones. (I should really try this on a real device lol)

    I'm currently only testing the WF - it's just released as a beta app. And the crash happens on my own watch once a day... I've set up everything and I do not change any settings anymore. And it just works 99% of the day for me...

    I will try logging the exception ...