From 2894157f15295354c68735c93aeb25df3628b126 Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Tue, 17 Jul 2012 16:30:33 +0100 Subject: [PATCH] MDL-34351 quiz cron: one broken overdue attempt should not kill cron It seems that sometimes trying to process an overdue quiz attempt can throw an exception. In that case, we need to catch it and report it nicely, and then carry on processing the rest of the attempts, rather than just killing the whole of cron processing. Also, there may be garbage quiz attempts where the associated quiz or course has been deleted. Skip those too. --- mod/quiz/cronlib.php | 49 ++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/mod/quiz/cronlib.php b/mod/quiz/cronlib.php index 111419c1f4b..7913b63cf58 100644 --- a/mod/quiz/cronlib.php +++ b/mod/quiz/cronlib.php @@ -57,27 +57,36 @@ class mod_quiz_overdue_attempt_updater { $count = 0; $quizcount = 0; foreach ($attemptstoprocess as $attempt) { - // If we have moved on to a different quiz, fetch the new data. - if (!$quiz || $attempt->quiz != $quiz->id) { - $quiz = $DB->get_record('quiz', array('id' => $attempt->quiz), '*', MUST_EXIST); - $cm = get_coursemodule_from_instance('quiz', $attempt->quiz); - $quizcount += 1; + try { + + // If we have moved on to a different quiz, fetch the new data. + if (!$quiz || $attempt->quiz != $quiz->id) { + $quiz = $DB->get_record('quiz', array('id' => $attempt->quiz), '*', MUST_EXIST); + $cm = get_coursemodule_from_instance('quiz', $attempt->quiz); + $quizcount += 1; + } + + // If we have moved on to a different course, fetch the new data. + if (!$course || $course->id != $quiz->course) { + $course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST); + } + + // Make a specialised version of the quiz settings, with the relevant overrides. + $quizforuser = clone($quiz); + $quizforuser->timeclose = $attempt->usertimeclose; + $quizforuser->timelimit = $attempt->usertimelimit; + + // Trigger any transitions that are required. + $attemptobj = new quiz_attempt($attempt, $quizforuser, $cm, $course); + $attemptobj->handle_if_time_expired($timenow, false); + $count += 1; + + } catch (moodle_exception $e) { + // If an error occurs while processing one attempt, don't let that kill cron. + mtrace("Error while processing attempt {$attempt->id} at {$attempt->quiz} quiz:"); + mtrace($e->getMessage()); + mtrace($e->getTraceAsString()); } - - // If we have moved on to a different course, fetch the new data. - if (!$course || $course->id != $quiz->course) { - $course = $DB->get_record('course', array('id' => $quiz->course), '*', MUST_EXIST); - } - - // Make a specialised version of the quiz settings, with the relevant overrides. - $quizforuser = clone($quiz); - $quizforuser->timeclose = $attempt->usertimeclose; - $quizforuser->timelimit = $attempt->usertimelimit; - - // Trigger any transitions that are required. - $attemptobj = new quiz_attempt($attempt, $quizforuser, $cm, $course); - $attemptobj->handle_if_time_expired($timenow, false); - $count += 1; } $attemptstoprocess->close();