From ea6dbf2d8fc8d84c299dba7b57db4d1dde3f91ed Mon Sep 17 00:00:00 2001 From: Eugene Fox Date: Fri, 12 Dec 2025 18:16:18 +0000 Subject: [PATCH] feat(dev): improved logging for failed calendar generation --- api/Program.cs | 52 +++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/api/Program.cs b/api/Program.cs index 687d59c..a2c508e 100644 --- a/api/Program.cs +++ b/api/Program.cs @@ -97,30 +97,38 @@ app.MapGet("/timetable/{facultyId}/{groupId}", async ( } } - DateTime semesterStartDate = await apiService.GetSemesterStartDateAsync(groupId); - string groupName = (await apiService.GetGroupsListAsync(facultyId, 0))[groupId]; - - string classesRaw = await apiService.GetScheduleDocumentAsync(groupId, TimetableType.Classes); - List timetable = [.. parsingService.ParseGeneralTimetable(classesRaw, semesterStartDate, groupName)]; - - TimetableType[] types = [TimetableType.Attestations, TimetableType.Exams, TimetableType.ExamsForExtramural]; - foreach (TimetableType type in types) + try { - classesRaw = await apiService.GetScheduleDocumentAsync(groupId, type); - timetable.AddRange(parsingService.ParseExamTimetable(classesRaw, groupName)); + DateTime semesterStartDate = await apiService.GetSemesterStartDateAsync(groupId); + string groupName = (await apiService.GetGroupsListAsync(facultyId, 0))[groupId]; + + string classesRaw = await apiService.GetScheduleDocumentAsync(groupId, TimetableType.Classes); + List timetable = [.. parsingService.ParseGeneralTimetable(classesRaw, semesterStartDate, groupName)]; + + TimetableType[] types = [TimetableType.Attestations, TimetableType.Exams, TimetableType.ExamsForExtramural]; + foreach (TimetableType type in types) + { + classesRaw = await apiService.GetScheduleDocumentAsync(groupId, type); + timetable.AddRange(parsingService.ParseExamTimetable(classesRaw, groupName)); + } + + Calendar calendar = new(); + calendar.Properties.Add(new CalendarProperty("X-WR-CALNAME", groupName)); + calendar.Properties.Add(new CalendarProperty("X-WR-TIMEZONE", "Europe/Moscow")); + calendar.Properties.Add(new CalendarProperty("REFRESH-INTERVAL;VALUE=DURATION", "PT6H")); + calendar.Events.AddRange(timetable); + calendar.AddTimeZone(new VTimeZone("Europe/Moscow")); + string serialized = new CalendarSerializer().SerializeToString(calendar)!; + + await File.WriteAllTextAsync(cacheFile, serialized); + logger.LogInformation("Cached timetable for group {GroupId} to {CacheFile}.", groupId, cacheFile); + return Results.Text(serialized, contentType: "text/calendar"); + } + catch (Exception ex) + { + logger.LogError(ex, "Failed to generate timetable for group {GroupId} of faculty {FacultyId}.", groupId, facultyId); + throw; } - - Calendar calendar = new(); - calendar.Properties.Add(new CalendarProperty("X-WR-CALNAME", groupName)); - calendar.Properties.Add(new CalendarProperty("X-WR-TIMEZONE", "Europe/Moscow")); - calendar.Properties.Add(new CalendarProperty("REFRESH-INTERVAL;VALUE=DURATION", "PT6H")); - calendar.Events.AddRange(timetable); - calendar.AddTimeZone(new VTimeZone("Europe/Moscow")); - string serialized = new CalendarSerializer().SerializeToString(calendar)!; - - await File.WriteAllTextAsync(cacheFile, serialized); - logger.LogInformation("Cached timetable for group {GroupId} to {CacheFile}.", groupId, cacheFile); - return Results.Text(serialized, contentType: "text/calendar"); }) .WithName("GetTimetable") .WithDescription("Gets the iCal timetable for the specified group.")