My watch face crashes when waking up in the morning

I’ve been working this for far too long…

If my watch loses contact with my phone during the night and enters or is in sleep mode, when I wake up the watch face is crashed until it gets connection back.  I know it is a cross platform problem (my 5 people who use it are complaining :D).  I cannot get the problem to duplicate in the simulator. I’ve tried setting the BLE to no connection and triggering different power modes.  I’ve deleted all my other watch faces of my watch to get a clean data capture this morning.  

The CIQ_LOG gives (in brief): Unexpected Type Error and a Failed invoking <symbol> errors located at hex 100013ce.  This converts to PC 268440526.  Line 134 is 268440514 and line 135 is 268440530. So...

(Sorry, code paste is crashing)
} else if (compId == wxId) {
     wxNow = (Complications.getComplication(wxId)).value;
     if (wxNow == null && hasWx) {
          try {
               var tempTemp = Weather.getCurrentConditions();
               wxNow = tempTemp.temperature;                                 //This is line 134
          } catch (e) {
               wxNow = -99.0;
          }
     }

     if ((ForC != System.UNIT_METRIC) && (wxNow != -99.0)) {
          wxNow = (wxNow * 9 / 5 + 32).toFloat();
      }

} else {
I changed my wxNow to always be a float versus trying to make it an integer (trying to guess the meaning of “Unexpected Type Error”).  That didn’t work.  Added the hasWx check
(hasWx = (Toybox has :Weather);).  I commented out my entire code dealing with low power mode, including onEnterSleep() and onExitSleep(), with no changes. I left onShow(), and it only gets called once and the only thing it does is the println() and WatchUi.requestUpdate();.
The only thing I can think of is that, when the system enters this sleep mode, it dumps all variables’ values.  But…I can’t trigger the crash in the sim.  Surely, it isn’t the "catch (e)” line, right?
So...
1) Do ya’ll see any error in this section of code?
2) How can I force the sim to test for this use case?
Thanks.
Jeff
  • You want to check tempTemp for null before you try to get temperature, and you also want to check temperature for null before you use it.

    the try/catch in your code won't catch this  Just do if/else calls..

  • Thanks.  I’ll switch it up.  Is there a way I can test this in the simulator?

    Also  (Yes…I’m needy), do I need to check all “internal" Comps this way?  For example, steps or battery?  If so, it seems like it would be a lot more efficient to ignore the Comps and just grab all the values from the system.

    Jeff

  • As jim_m_58 said, the value returned by Weather.getCurrentConditions() can be null. Additionally, CurrentConditions.temperature can be null.

    Both of these things are explicitly stated in the API documentation:

    https://developer.garmin.com/connect-iq/api-docs/Toybox/Weather.html#getCurrentConditions-instance_function

    getCurrentConditions() as Weather.CurrentConditions or Null

    developer.garmin.com/.../CurrentConditions.html

    var temperature as Lang.Numeric or Null

    If you enable type checking, the type checker will prevent you from using these values without checking for null. This would've avoided the crash in the first place.

    Finally, there is a subtle problem with your conversion to Fahrenheit. As seen above, CurrentConditions.temperature is Numeric, which means it can either be a floating-point value (Float/Double) or an integer (Number/Long). If it's an integer, the calculation will not work as expected. Since wxNow * 9 will be a multiplication of 2 integers, the result will be an integer, and that result will be divided by 5, which is also an integer. Therefore, the division by 5 will be performed as integer division, which throws away the remainder and returns an integer / whole number as a result. This is clearly not what you want - in this case you want a fractional / floating-point result. The solution is to make sure one of the numbers involved in the division is a float.

    Here's a modified version of your code which addresses the above issues (missing null checks, and fahrenheit conversion issue):

    EDIT: Old and busted sample: https://pastebin.com/BFRtqdMN

    There is another potential problem where getComplication will throw an error if the given complication is not found. I'm not 100% sure if this is possible in your case (since I can't see the full context). In my modified version of your code, I didn't bother addressing it.

    EDIT: new and better sample:

    https://pastebin.com/Rfu6GeKb

  • Thanks for the further information and example.  

    The -99 was part of my “why isn’t this working” process.  I was trying to force it to show -99 if all else failed.  

    I have corrected the equation for consistency.  I also decided to do all the error checking and correcting in the functions that “use” the Complications.  

  • No problem! You may have noticed my example has a subtle crash bug if hasWx is false. Even though you won't use the code, I'll update the sample to avoid that bug and to not use -99.0 at all.