Acknowledged

Watch face crash on some watches, it works on simulator.

My watch face (https://apps.garmin.com/en-US/apps/d44a137e-7a1e-4b67-9aa6-133d48db745c) is crashing when using one function on some watches, Forerunner 45 and Fenix 7s that I could get feedback from. When I try in the simulator for those watches, it works fine and it also works fine on other watches, like Forerunner 645 (that I own).

This is the code that is crashing, I tried to wrap up everything on try catches without luck. I am starting to get multiple complaints.

Here is the offending code, I was able to confirm the function getHRMax is working if used alone (via other functionality of my watch face).

    //! Get the VO2Max. Try first from watch, then calculate.
    //! @return [Float] Floating number with VO2Max approximation
    function getVO2Max() {
		var vo2max = null;
		var profile = null;

		try {
			profile = UserProfile.getProfile();
		}
		catch(ex) {
		}

		// RFCS-64 2022/7/24 - Check if can get VO2Max from watch directly
		if (null != profile && profile has :vo2maxCycling && profile has :vo2maxRunning) {
			try {
				// RFCS-64 2022/7/24 - Check current sport from watch
				if (UserProfile.HR_ZONE_SPORT_BIKING == UserProfile.getCurrentSport()) {				
					vo2max = profile.vo2maxCycling;
				}
				else { // RFCS-64 2022/7/24 - Any other sport, get running VO2Max
					vo2max = profile.vo2maxRunning;
				}
			}
			catch (ex) {
				// If could not get the watch VO2Max, try to calculate
				vo2max = RunFocusData.calculateVO2Max();
			}
		}
		else {
			// If version of the watch does not have VO2Max exposed, calculate
			vo2max = RunFocusData.calculateVO2Max();
		}

		return vo2max;
    }
    
    //! Calculate current VO2Max based on simple formula to give approximation
    //! VO2Max = ( HRmax / HRrest ) * 15.3
    //! @return [Float] Floating number with VO2Max approximation
    function calculateVO2Max() {
		var rhr = null;
		var hrmax = null;
		var vo2max = null;

		var profile = null;
		try {
			profile = UserProfile.getProfile();
		}
		catch(ex) {
		}
		finally {
			// RFCS-64 2022/7/24 - Watch API does not have VO2Max exposed, calculate
			if (null != profile) {
				try {
					rhr = profile.restingHeartRate;
				}
				catch (ex) {
				}
				finally {
					if (null != rhr) {
						try {
							hrmax = RunFocusData.getHRMax();
						}
						catch (ex) {
						}
						
						if (null != hrmax) {
							try {
								// RFCS-64 2022/7/24 - Make sure it converts to float
								vo2max = Math.round((hrmax.toFloat() / rhr) * 15.3);
							} catch (ex) {
								vo2max = null;
							}
						}
					}
				}
			}
		}
		
		return vo2max;
	}
    
	// RFCS-69 2022/7/24 - Trying to make sure it doesnt crash
    //! Get HRMax from HR zone 5
    //! @return [Number] HRMax
    function getHRMax() {
		var HRMax = null;
		var genericZoneInfo = null;
		try {
			genericZoneInfo = UserProfile.getHeartRateZones(UserProfile.HR_ZONE_SPORT_RUNNING);
			// RFCS-69 2022/7/24 - An array was returned and it has at least one element
			if (genericZoneInfo has :size && genericZoneInfo.size() > 0) {
				HRMax = genericZoneInfo[genericZoneInfo.size()-1];
			}
		}
		catch (ex) {
		}

		return HRMax;
    }

I wonder if anyone is experiencing the same or may have an idea of what is going on. It looks similar on reports about using Moment.subtract as reported here https://forums.garmin.com/developer/connect-iq/i/bug-reports/runtime-error-with-moment-subtract-when-subtracting-a-duration but maybe some other function?

Remember, it is working fine on simulator and other watches, only on some watches that it doesnt work.

Parents
  • Maybe it's a design/implementation inconsistency where some watches return 0 instead of null, when the RHR is invalid. It's a known design decision that UserProfile.restingHeartRate is initially invalid/null when it hasn't been set by the user.

    It is too bad that there's lots of errors that can't be caught in Monkey C. As a general rule, the only exceptions that are thrown in Monkey C are explicitly documented for a given method.

Comment
  • Maybe it's a design/implementation inconsistency where some watches return 0 instead of null, when the RHR is invalid. It's a known design decision that UserProfile.restingHeartRate is initially invalid/null when it hasn't been set by the user.

    It is too bad that there's lots of errors that can't be caught in Monkey C. As a general rule, the only exceptions that are thrown in Monkey C are explicitly documented for a given method.

Children
No Data