DataField - System Error - Failed to Invoke <symbol> on Initialize

I am getting a System Error when trying to createField on initialize (to add FIT contributor). Error only happens on some devices (like Fenix7) 
Error: System Error
Details: 'Failed invoking <symbol>'
Time: 2022-05-19T14:38:19Z
Part-Number: 006-B3907-00
Firmware-Version: '8.21'
Language-Code: eng
ConnectIQ-Version: 4.0.10
Filename: C5I65603
 
The stack trace indicates the error is happening on the first createField  call.
 function initialize(dataField) {
        try {
            mCurrentInclineField = dataField.createField("inclineRunn", INCLINE_FIELD_ID, FitContributor.DATA_TYPE_FLOAT, { :nativeNum=>NATIVE_NUM_FIT_RECORD_GRADE, :mesgType=>FitContributor.MESG_TYPE_RECORD, :units=>"%" });
            mTotalAscentLapField = dataField.createField("total_ascent", TOTAL_ASCENT_LAP_FIELD , FitContributor.DATA_TYPE_FLOAT, { :nativeNum=>NATIVE_NUM_FIT_LAP_TOTAL_ASCENT , :mesgType=>FitContributor.MESG_TYPE_LAP, :units=>"m" });
            mTotalAscentSessionField = dataField.createField("total_ascent", TOTAL_ASCENT_SESSION_FIELD , FitContributor.DATA_TYPE_FLOAT, {:nativeNum=>NATIVE_NUM_FIT_SESSION_TOTAL_ASCENT, :mesgType=>FitContributor.MESG_TYPE_SESSION, :units=>"m" });
            mTotalDescentLapField = dataField.createField("total_descent", TOTAL_DESCENT_LAP_FIELD , FitContributor.DATA_TYPE_FLOAT, { :nativeNum=>NATIVE_NUM_FIT_LAP_TOTAL_DESCENT , :mesgType=>FitContributor.MESG_TYPE_LAP, :units=>"m" });
            mTotalDescentSessionField = dataField.createField("total_descent", TOTAL_DESCENT_SESSION_FIELD , FitContributor.DATA_TYPE_FLOAT, { :nativeNum=>NATIVE_NUM_FIT_SESSION_TOTAL_DESCENT, :mesgType=>FitContributor.MESG_TYPE_SESSION, :units=>"m" });
    
            mTotalDistanceLapField = dataField.createField("total_distance", TOTAL_DISTANCE_LAP_FIELD , FitContributor.DATA_TYPE_FLOAT, { :nativeNum=>NATIVE_NUM_FIT_LAP_TOTAL_DISTANCE , :mesgType=>FitContributor.MESG_TYPE_LAP, :units=>"m" });
            mTotalDistanceSessionField = dataField.createField("total_distance", TOTAL_DISTANCE_SESSION_FIELD , FitContributor.DATA_TYPE_FLOAT, { :nativeNum=>NATIVE_NUM_FIT_SESSION_TOTAL_DISTANCE, :mesgType=>FitContributor.MESG_TYPE_SESSION, :units=>"m" });
            mCurrentInclineField.setData(0);
            mTotalAscentLapField.setData(0);
            mTotalAscentSessionField.setData(0);
            mTotalAscentLapField.setData(0);
            mTotalAscentSessionField.setData(0);
            mTotalDescentSessionField.setData(0);
            mTotalDescentLapField.setData(0);
        }
        catch(exception) {
             System.println("FIT Init Exception " + exception);
        }

    }
Runs fine in the emulator for all devices. 
Anyone have any ideas?


Top Replies

  • However, in ERA I see a lot of "System Error" issues for other users. But what is really strange - these errors point not to the first line with FIT field creation but to the field…
  • On watches where you can only have 2 CIQ DFs in an activity, if every DF used less than 1/2 of the possible fields, that would be a work around. 

    Not to state the obvious, but that only works…

All Replies

  • Will try to refresh this topic with the same issue I recently encountered.

    I have a FIT Contributor functionality with 14 fields that looks like this:

    public class MyView extends DataField {
    
        public function initialize() {
            DataField.initialize();
            
            // other unrelated to the FIT contribution code
    
            FitFields.createFields(self);
        }
    }    
        
        
    import Toybox.FitContributor;
    import Toybox.WatchUi;
    
    public class FitFields {
        public static var grade as Field?;
        public static var avgSpeedMetric as Field?;
        public static var avgSpeedStatute as Field?;
        public static var avgHeartRate as Field?;
        public static var avgPower as Field?;
        public static var normalizedPower as Field?;
        public static var totalAscentMetric as Field?;
        public static var totalAscentStatute as Field?;
        public static var batteryLevel as Field?;
        public static var minGarde as Field?;
        public static var maxGrade as Field?;
        public static var batteryRemained as Field?;
        public static var batteryDischarge as Field?;
        public static var batteryDischargeRate as Field?;
    
        public static function createFields(dataField as DataField) as Void {
            grade = dataField.createField("grade", 0, FitContributor.DATA_TYPE_SINT8, {
                :mesgType => FitContributor.MESG_TYPE_RECORD,
                :units => "percent",
            });
    
            avgSpeedMetric = dataField.createField("average_speed_metric", 1, FitContributor.DATA_TYPE_FLOAT, {
                :mesgType => FitContributor.MESG_TYPE_RECORD,
                :units => "kmh",
            });
    
            avgSpeedStatute = dataField.createField("average_speed_statute", 2, FitContributor.DATA_TYPE_FLOAT, {
                :mesgType => FitContributor.MESG_TYPE_RECORD,
                :units => "mph",
            });
    
            avgHeartRate = dataField.createField("average_heart_rate", 3, FitContributor.DATA_TYPE_UINT8, {
                :mesgType => FitContributor.MESG_TYPE_RECORD,
                :units => "bpm",
            });
    
            avgPower = dataField.createField("average_power", 4, FitContributor.DATA_TYPE_UINT16, {
                :mesgType => FitContributor.MESG_TYPE_RECORD,
                :units => "watts",
            });
    
            normalizedPower = dataField.createField("normalized_power", 5, FitContributor.DATA_TYPE_UINT16, {
                :mesgType => FitContributor.MESG_TYPE_RECORD,
                :units => "watts",
            });
    
            totalAscentMetric = dataField.createField("total_ascent_metric", 6, FitContributor.DATA_TYPE_UINT16, {
                :mesgType => FitContributor.MESG_TYPE_RECORD,
                :units => "m",
            });
    
            totalAscentStatute = dataField.createField("total_ascent_statute", 7, FitContributor.DATA_TYPE_UINT16, {
                :mesgType => FitContributor.MESG_TYPE_RECORD,
                :units => "ft",
            });
    
            batteryLevel = dataField.createField("battery_level", 8, FitContributor.DATA_TYPE_UINT8, {
                :mesgType => FitContributor.MESG_TYPE_RECORD,
                :units => "percent",
            });
    
            minGarde = dataField.createField("min_grade", 9, FitContributor.DATA_TYPE_SINT8, {
                :mesgType => FitContributor.MESG_TYPE_SESSION,
                :units => "percent",
            });
    
            maxGrade = dataField.createField("max_grade", 10, FitContributor.DATA_TYPE_SINT8, {
                :mesgType => FitContributor.MESG_TYPE_SESSION,
                :units => "percent",
            });
    
            batteryRemained = dataField.createField("battery_remained", 11, FitContributor.DATA_TYPE_UINT8, {
                :mesgType => FitContributor.MESG_TYPE_SESSION,
                :units => "percent",
            });
    
            batteryDischarge = dataField.createField("battery_discharge", 12, FitContributor.DATA_TYPE_UINT8, {
                :mesgType => FitContributor.MESG_TYPE_SESSION,
                :units => "percent",
            });
    
            batteryDischargeRate = dataField.createField("battery_discharge_rate", 13, FitContributor.DATA_TYPE_FLOAT, {
                :mesgType => FitContributor.MESG_TYPE_SESSION,
                :units => "percent/hour",
            });
        }
    }

    It works without issues on my own Edge 1030 device and in the sim for all supported Edge devices.

    However, in ERA I see a lot of "System Error" issues for other users. But what is really strange - these errors point not to the first line with FIT field creation but to the field 6 or field 8 creation (totalAscentMetric and batteryLevel fields accordingly).

    Among the hypotheses, I thought that it may be either some incomplete state of the MyView instance when it's passed to the FitFields class as self or some buggy FIT data type. But both theories seem to be incorrect - in the first case it would fail on the first ever field creation (grade), and in the second case it would fail on the creation of the first datafield with the same data type (avgHeartRate and avgPower accordingly).

    This failing "in the middle" looks extremely strange to me

  • However, in ERA I see a lot of "System Error" issues for other users. But what is really strange - these errors point not to the first line with FIT field creation but to the field 6 or field 8 creation (totalAscentMetric and batteryLevel fields accordingly).

    In your case, I think it's because there's a limit to the total number of FIT fields for *all* CIQ data fields installed in a given activity. (Yes, this sucks for obvious reasons).

    There have been several reports of CIQ data fields like Stryd Zones (which records lots of FIT fields) crashing due to the presence of another CIQ data field which also records FIT fields.

    So you're likely seeing this fail "in the middle" and only for some users, because those users probably have another CIQ data field for that activity which also creates FIT fields. You can try to test this theory by asking your users to try to remove any other CIQ field from the activity, or by adding a 2nd CIQ field to your activity which records FIT fields.

  • off-topic: what is ERA?

  • you are totally right. I just tried to experiment by mixing both prod and beta versions of my datafield on the screen, variating the number of fields in the beta app step by step. It turns out that it starts to crash on Edge 1030 when the total number of fields is 22. Btw, the same count is mentioned here https://forums.garmin.com/developer/connect-iq/f/discussion/234758/what-is-the-limiting-number-of-developer-fields-that-can-be-added-under-session/1115548#1115548

    This really sucks - we can't know how many fields are written into FIT by other apps and we can't catch the exception because this is a non-recoverable System error. Something that we can't control at all. The best that we can do is disable FIT contribution by default and allow the user to enable it in the app settings at his own risk. Totally frustrating

  • It's more complex than that.  Another user's data field that only creates one or two fields could be the one that sees the error/crash, with  no indication your DF was involved.  The only real work around at this point is reduce the number of fields in your data field.

  • that workaround only REALLY works if you reduce it to 0

  • On watches where you can only have 2 CIQ DFs in an activity, if every DF used less than 1/2 of the possible fields, that would be a work around.  This is nothing new, as FlowState mentioned, Even Styrd Zones was bit by this not long after fitcontrib was introduced.

  • oh, yeah, let's not get into game theory, please...

  • It's more like being respectful of other devs and handling something that Garmin knows about and has been happening for years.