This published Fitbit app utilizes an API provided by sunrise-sunset.org to get the sunrise and sunset times for a given date and location. As of August 9. 2022, the sunrise-sunset API https call has an invalid certificate creating an issue. Fortunately a user notified me of this problem. Since the API certificate is invalid, returned data is throwing an error that wasn’t being properly handled in the code [Note: sunrise-sunset.org updated their certificate allowing the API to respond properly].
I am currently working on an update to the companion code to handle the unexpected error, which is discussed below. Even with this error handling, if the sunrise-sunset.org API certificate is not resolved, this will required a change in how the sunrise and sunset times are obtained. Currently my plan is to publish an app update by October 1, 2022 [Note: An app update to handle malformed JSON responses was published August 24, 2022, Version 1.1.0].
This issue with the unexpected error is found in the companion app (the code that runs on the Fitbit app on your phone). In the Fitbit architecture, messages are passed between your watch and the companion app (see this Fitbit guide for more information). The companion app provides the gateway to the Internet. The API call uses fetch() with the api calling string. The response should be a JSON string, which is parsed and the data sent back to the watch for display.
The solution to handle the unexpected error is simple. I added a “catch” statement to handle the error and pass an error indicator back to the watch. The companion code segment is show below. This code waits for a message from the watch to get sunrise and sunset data. The companion app builds the api string and then makes the api call using fetch(). The JSON string components are extracted and sent back to the watch for display. The catch sends back-100 lat and lon to indicate an error has occurred.
// Listen for messages from the device
// Message has the date we need, companion has everything else
messaging.peerSocket.onmessage = function(evt) {
if (evt.data) {
console.log("evt.data " + JSON.stringify(evt.data));
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
// build api string
var apiString = "https://api.sunrise-sunset.org/json?lat=" + lat + "&lng=" + lng + "&date=" + evt.data.getDate;
console.log(apiString);
// go to the web to get sun rise/set data that is returned in a json string
fetch(apiString)
.then(function(response) {return response.json();})
.then(function(json) {
console.log("Got JSON response from server:" + JSON.stringify(json));
messaging.peerSocket.send({
getDate: evt.data.getDate, lat: lat, lng: lng, rise: json.results.sunrise, set: json.results.sunset});
})
.catch(function(err) {
console.error('Error during fetch ' + err.code);
messaging.peerSocket.send({
getDate: evt.data.getDate, lat: -100, lng: -100, rise: 0, set: 0}); // network data error occurred
});
}
}
}
When the watch receives a message with the error indicators, the watch displays that an error has occurred but continues to allow the user to change dates and try again.
