Aldaviva / GamesDoneQuickCalendarFactory

📅 Generate a list of events for GDQ in iCalendar (ICS) format
https://aldaviva.com/docs/gdq.ics
Apache License 2.0
11 stars 0 forks source link

Service crashing during "Speedrun Stage @ PAX West" (2024-08-30) #22

Closed Aldaviva closed 1 month ago

Aldaviva commented 2 months ago

Service is repeatedly crashing with uncaught exception

Application: GamesDoneQuickCalendarFactory.exe
CoreCLR Version: 8.0.824.36612
.NET Version: 8.0.8
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Collections.Generic.KeyNotFoundException: The given key 'SSAtPAXWest/Super Mario Bros.' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at GamesDoneQuickCalendarFactory.Services.GoogleCalendarSynchronizer.<sync>b__8_4(CalendarEvent icsEvent) in C:\Users\Ben\Documents\Projects\GamesDoneQuickCalendarFactory\GamesDoneQuickCalendarFactory\Services\GoogleCalendarSynchronizer.cs:line 73
   at System.Linq.Enumerable.WhereEnumerableIterator`1.ToList()
   at GamesDoneQuickCalendarFactory.Services.GoogleCalendarSynchronizer.sync(Object sender, Calendar newCalendar) in C:\Users\Ben\Documents\Projects\GamesDoneQuickCalendarFactory\GamesDoneQuickCalendarFactory\Services\GoogleCalendarSynchronizer.cs:line 72
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_1(Object state)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
 d | 2024-08-30 21:11:33.120 | GoogleCalendarSynchronizer | Downloading existing events from Google Calendar e8f4102e721e2a1400f786a11e629ddd8a9a8f984bf1f2884b96afb0aac6f947@group.calendar.google.com
 d | 2024-08-30 21:11:33.736 | GoogleCalendarSynchronizer | Found 0 existing events in Google Calendar
 d | 2024-08-30 21:11:33.741 | CalendarPoller             | Polling GDQ schedule
 t | 2024-08-30 21:11:33.743 | CalendarGenerator          | Downloading schedule from Games Done Quick website
 i | 2024-08-30 21:11:34.667 | CalendarPoller             | GDQ schedule changed, new etag is "1725066694667"
Unhandled exception. System.Collections.Generic.KeyNotFoundException: The given key 'SSAtPAXWest/Super Mario Bros.' was not present in the dictionary.
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at GamesDoneQuickCalendarFactory.Services.GoogleCalendarSynchronizer.<sync>b__8_4(CalendarEvent icsEvent) in C:\Users\Ben\Documents\Projects\GamesDoneQuickCalendarFactory\GamesDoneQuickCalendarFactory\Services\GoogleCalendarSynchronizer.cs:line 73
   at System.Linq.Enumerable.WhereEnumerableIterator`1.ToList()
   at GamesDoneQuickCalendarFactory.Services.GoogleCalendarSynchronizer.sync(Object sender, Calendar newCalendar) in C:\Users\Ben\Documents\Projects\GamesDoneQuickCalendarFactory\GamesDoneQuickCalendarFactory\Services\GoogleCalendarSynchronizer.cs:line 72
   at System.Threading.Tasks.Task.<>c.<ThrowAsync>b__128_1(Object state)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart()
 i | 2024-08-30 21:11:34.765 | Lifetime                   | Now listening on: http://0.0.0.0:8081
 i | 2024-08-30 21:11:34.766 | Lifetime                   | Application started. Press Ctrl+C to shut down.
 i | 2024-08-30 21:11:34.766 | Lifetime                   | Hosting environment: Production
 i | 2024-08-30 21:11:34.766 | Lifetime                   | Content root path: C:\Programs\Servers\GamesDoneQuickCalendarFactory

It's always the same stacktrace with the same missing dictionary key SSAtPAXWest/Super Mario Bros..

It only crashes if Google Calendar synchronization is enabled. It crashes almost immediately after the program starts.

Aldaviva commented 2 months ago

This is caused by running the same game twice in the same GDQ event, because the unique key for runs is a compound key made up of the event name and the game name, so if they're both the same they collide, and the program tries to update one in Google Calendar when it should actually be creating it. The iCal UUID needs to be different to account for this possibility. image

Aldaviva commented 2 months ago

Modified iCal UUID for events to contain the GDQ event name, run name, and run description (for example Warpless in the screenshot above). Google Calendar is now being populated with runs and the service isn't crashing anymore.

Aldaviva commented 2 months ago

This is now fixed in production, but still needs unit tests to guarantee its behavior and prevent future regressions. Also the tests break in local development because they try to upload to Google Calendar, corrupting the calendar state and requiring a UUID change to clear.

Aldaviva commented 1 month ago

Fixed tests.