From a9264b007ffa4bf4ae04069bb14f56b6b3f591ea Mon Sep 17 00:00:00 2001 From: Anna Larch Date: Wed, 18 Jan 2023 12:30:58 +0100 Subject: [PATCH] fix(dav): catch MaxInstancesExceedeException for recurring events without end date Ref https://github.com/nextcloud/calendar/issues/4811 Signed-off-by: Anna Larch --- .../lib/CalDAV/Reminder/ReminderService.php | 73 ++++++++++--------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/apps/dav/lib/CalDAV/Reminder/ReminderService.php b/apps/dav/lib/CalDAV/Reminder/ReminderService.php index 3fb8cf9ebe509..ffb829f454a0d 100644 --- a/apps/dav/lib/CalDAV/Reminder/ReminderService.php +++ b/apps/dav/lib/CalDAV/Reminder/ReminderService.php @@ -482,49 +482,54 @@ private function deleteOrProcessNext(array $reminder, return; } - while ($iterator->valid()) { - $event = $iterator->getEventObject(); - - // Recurrence-exceptions are handled separately, so just ignore them here - if (\in_array($event, $recurrenceExceptions, true)) { - $iterator->next(); - continue; - } - - $recurrenceId = $this->getEffectiveRecurrenceIdOfVEvent($event); - if ($reminder['recurrence_id'] >= $recurrenceId) { - $iterator->next(); - continue; - } + try { + while ($iterator->valid()) { + $event = $iterator->getEventObject(); - foreach ($event->VALARM as $valarm) { - /** @var VAlarm $valarm */ - $alarmHash = $this->getAlarmHash($valarm); - if ($alarmHash !== $reminder['alarm_hash']) { + // Recurrence-exceptions are handled separately, so just ignore them here + if (\in_array($event, $recurrenceExceptions, true)) { + $iterator->next(); continue; } - $triggerTime = $valarm->getEffectiveTriggerTime(); - - // If effective trigger time is in the past - // just skip and generate for next event - $diff = $now->diff($triggerTime); - if ($diff->invert === 1) { + $recurrenceId = $this->getEffectiveRecurrenceIdOfVEvent($event); + if ($reminder['recurrence_id'] >= $recurrenceId) { + $iterator->next(); continue; } - $this->backend->removeReminder($reminder['id']); - $alarms = $this->getRemindersForVAlarm($valarm, [ - 'calendarid' => $reminder['calendar_id'], - 'id' => $reminder['object_id'], - ], $reminder['event_hash'], $alarmHash, true, false); - $this->writeRemindersToDatabase($alarms); + foreach ($event->VALARM as $valarm) { + /** @var VAlarm $valarm */ + $alarmHash = $this->getAlarmHash($valarm); + if ($alarmHash !== $reminder['alarm_hash']) { + continue; + } - // Abort generating reminders after creating one successfully - return; - } + $triggerTime = $valarm->getEffectiveTriggerTime(); - $iterator->next(); + // If effective trigger time is in the past + // just skip and generate for next event + $diff = $now->diff($triggerTime); + if ($diff->invert === 1) { + continue; + } + + $this->backend->removeReminder($reminder['id']); + $alarms = $this->getRemindersForVAlarm($valarm, [ + 'calendarid' => $reminder['calendar_id'], + 'id' => $reminder['object_id'], + ], $reminder['event_hash'], $alarmHash, true, false); + $this->writeRemindersToDatabase($alarms); + + // Abort generating reminders after creating one successfully + return; + } + + $iterator->next(); + } + } catch (MaxInstancesExceededException $e) { + // Using debug logger as this isn't really an error + $this->logger->debug('Recurrence with too many instances detected, skipping VEVENT', ['exception' => $e]); } $this->backend->removeReminder($reminder['id']);