Invalid value in Field.setData

I started to get some ERA errors like this:

Error Name: Invalid Value
Devices:
    Venu® Sq: 5.10
    Forerunner® 965: 21.22
Backtrace:
    MyView.compute:303

As far as I understand from the docs ActivityInfo.currentLocationAccuracy is supposed to be Position.Quality or Null, meaning only values: Null, 0,1,2,3,4 will ever be there. How come the below code produces Invalid Value error?

The relevant code is:

class MyView {
  var gpsAccuracy as Number or Position.Quality = 0;
  var gpsAccuracyField as Field?;

  initialize() {
    if (isGpsEnabledByUser) {
      gpsAccuracyField = session.createField("gpsAccuracy", 8, Fit.DATA_TYPE_UINT8, { :mesgType => Fit.MESG_TYPE_RECORD, :units => "" });
    }
  }

  function compute(info as Activity.Info) as Void {
    var gpsAccuracy = ifNullThenZero(info.currentLocationAccuracy) as Number;
    if (gpsAccuracy != self.gpsAccuracy) {
      self.gpsAccuracy = gpsAccuracy;
      if (gpsAccuracyField != null) {
        gpsAccuracyField.setData(gpsAccuracy); // line 303
      }
    }
  }

  function onTimer() as Void {
    var info = Activity.getActivityInfo();
    if (info != null) {
      compute(info as Activity.Info);
    }
  }

  function ifNullThenZero(val as Number or Float or Null) as Number or Float {
    return val != null ? val : 0;
  }
}

  • It was my assumption from the start that setData() itself is crashing, not the call to setData()

    When I see an Invalid Value error in CIQ, it always seems to be caused by code inside an API function which doesn’t like the value/type of an argument which was passed in.

    Here's an example of an Invalid Value error which seems to be coming from inside an API function call, not at the point of the call itself:

    (42).format("%k"); // <=== stack trace points here

    Error: Invalid Value
    Details: Unexpected input to format

    It doesn't seem like the format string would or could be parsed at the point of the function call.

  • So I released a new version with the following code, and I got today 2 new Invalid Value exceptions:

    ( If you're already improving the forum settings, can you try to fix this thing that we can't post code in the "insert code" box?)

    var gpsAccuracy = ifNullThenZero(info.currentLocationAccuracy) as Number;
    if (gpsAccuracy != self.gpsAccuracy) {
      self.gpsAccuracy = gpsAccuracy;
      if (gpsAccuracyField != null) {
        if (gpsAccuracy < 0) {
          setGpsDataNegative(gpsAccuracy);
        } else if (gpsAccuracy > 4) {
          setGpsDataTooBig(gpsAccuracy);
        } else if (gpsAccuracy instanceof Lang.Number) {
          gpsAccuracyField.setData(gpsAccuracy); // Invalid Value
        } else {
          setGpsDataNonNumber(gpsAccuracy);
        }
      }
    }
    So it looks like info.currentLocationAccuracy has a Number value that is out of the Fit.DATA_TYPE_UINT8 limits, but also it's not negative and not greater than 4!??????!±?!??!?!? Sorry, but the only thing I can say is WTF!?
    The 2nd Invalid Value comes from another fit field, this time UINT32 and Number value, and unfortunately even the try/catch doesn't help:
    var stepsActivityField as Number = 0;
    
    initialize() {
        stepsActivityField = baseView.createField(steps, 0, Fit.DATA_TYPE_UINT32, { :mesgType => Fit.MESG_TYPE_SESSION, :units => stepsUnits });
    }
    
    function compute() as Void {
        // both consolidatedSteps, daySteps, stepsWhenTimerBecameActive are Numbers
    	steps = consolidatedSteps + daySteps - stepsWhenTimerBecameActive;
    
    	try {
    		stepsActivityField.setData(steps); // Invalid Value
    	} catch (e) {
    		errorRelease("steps: " + steps + "; " + e.getErrorMessage());
    		e.printStackTrace();
    	}
    }