tcgoetz / GarminDB

Download and parse data from Garmin Connect or a Garmin watch, FitBit CSV, and MS Health CSV files into and analyze data in Sqlite serverless databases with Jupyter notebooks.
GNU General Public License v2.0
1.1k stars 138 forks source link

KeyError when downloading activity due to NULL activityName #231

Open ajamess opened 3 months ago

ajamess commented 3 months ago

I had an activity that did not have a title by default which caused a KeyError. I resolved this by updating the activity in Garmin Connect manually, but I think the script could handle this scenario better.

The way this activity appeared in Garmin Connect was the title here was marked as "Untitled" in the blue circle. I have since given it a title (Treadmill Running, as in the screenshot) to address the script issue.

image

The behavior of the script when encountering an "untitled" activity like this is to throw a KeyError

python ./garmindb_cli.py --all --download --import --analyze

___Downloading All Data___

Getting activities: 'C:\Users\<redacted>\HealthData\FitFiles\Activities' (3000) temp C:\Users\<redacted>\AppData\Local\Temp\tmp2ktvw9dt

 66%|████████████████████████████████████████████▏                      | 1380/2095 [00:00<00:00, 18094.66activities/s]

Traceback (most recent call last):

  File "C:\users\<redacted>\appdata\roaming\Python\Python312\Scripts\garmindb_cli.py", line 368, in <module>
    main(sys.argv[1:])

  File "C:\users\<redacted>\appdata\roaming\Python\Python312\Scripts\garmindb_cli.py", line 349, in main
    download_data(args.overwrite, args.latest, args.stats)

  File "C:\users\<redacted>\appdata\roaming\Python\Python312\Scripts\garmindb_cli.py", line 125, in download_data
    download.get_activities(activities_dir, activity_count, overwite)

  File "C:\Users\<redacted>\AppData\Roaming\Python\Python312\site-packages\garmindb\download.py", line 246, in get_activities
    activity_name_str = conversions.printable(activity['activityName'])
                                              ~~~~~~~~^^^^^^^^^^^^^^^^

KeyError: 'activityName'

When "activityName" is NULL, like in my example, there is no Key to look up in the activity[] dictionary, so the script errors.

image

The fix was for me to run PDB and find the failing activity ID, then manually update the title in Garmin Connect so the script would no longer fail. I am not sure how the activity ended up with no name. It might be some corner case on the Garmin side, because out of 2095 activities I imported, only 1 of them had this problem.

I see a few potential fixes to this corner case:

  1. When activityName is NULL, fall back to the activity description as the activityName
  2. When activityName is NULL, fall back to the activity ID as the activityName
  3. When activityName is NULL, throw an exception with an error message instructing the user to navigate to "https://connect.garmin.com/modern/activity/" to manually update the title. This was my solution (see first screenshot).

Thanks for your hard work on this script! It's very cool.

ajamess commented 3 months ago

I found another example of such a broken activity:

image

Turns out I had a few hundred of them. I was able to bulk update their titles to "Other" in the screenshot below. The broken ones show up as "untitled", which map to a NULL activity name. I think many old activities may have this problem. So it is likely worth fixing the issue for folks like me who have been using garmin watches for a long time. I have activities going back to 2011, and it appears the issue started with these names around the 2015 timeframe. Here are some examples:

image