@@ -550,55 +550,68 @@ async sub pre_header_initialize ($c) {
550550 )
551551 )
552552 {
553- # Assign the set, get the right name, version number, etc., and redefine the $set and $problem for the
554- # remainder of this method.
553+ # Attempt to assign the set.
555554 my $setTmpl = $db -> getUserSet($effectiveUserID , $setID );
556- assignSetVersionToUser($db , $effectiveUserID , $setTmpl );
557- $setVersionNumber ++;
558-
559- # Get a clean version of the set and merged version to use in the rest of the routine.
560- my $cleanSet = $db -> getSetVersion($effectiveUserID , $setID , $setVersionNumber );
561- $set = $db -> getMergedSetVersion($effectiveUserID , $setID , $setVersionNumber );
562- $set -> visible(1);
563-
564- $problem = $db -> getMergedProblemVersion($effectiveUserID , $setID , $setVersionNumber , $setPNum [0]);
565-
566- # Convert the floating point value from Time::HiRes to an integer for use below. Truncate toward 0.
567- my $timeNowInt = int ($c -> submitTime);
568-
569- # Set up creation time, and open and due dates.
570- my $ansOffset = $set -> answer_date - $set -> due_date;
571- $set -> version_creation_time($timeNowInt );
572- $set -> open_date($timeNowInt );
573- # Figure out the due date, taking into account the time limit cap.
574- my $dueTime =
575- $timeLimit == 0 || ($set -> time_limit_cap && $c -> submitTime + $timeLimit > $set -> due_date)
576- ? $set -> due_date
577- : $timeNowInt + $timeLimit ;
578-
579- $set -> due_date($dueTime );
580- $set -> answer_date($set -> due_date + $ansOffset );
581- $set -> version_last_attempt_time(0);
582-
583- # Put this new info into the database. Put back the data needed for the version, and leave blank any
584- # information that should be inherited from the user set or global set. Set the data which determines
585- # if a set is open, because a set version should not reopen after it's complete.
586- $cleanSet -> version_creation_time($set -> version_creation_time);
587- $cleanSet -> open_date($set -> open_date);
588- $cleanSet -> due_date($set -> due_date);
589- $cleanSet -> answer_date($set -> answer_date);
590- $cleanSet -> version_last_attempt_time($set -> version_last_attempt_time);
591- $cleanSet -> version_time_limit($set -> version_time_limit);
592- $cleanSet -> attempts_per_version($set -> attempts_per_version);
593- $cleanSet -> assignment_type($set -> assignment_type);
594- $db -> putSetVersion($cleanSet );
595-
596- # This is a new set version, so it's open.
597- $versionIsOpen = 1;
598-
599- # Set the number of attempts for this set to zero.
600- $currentNumAttempts = 0;
555+ eval { assignSetVersionToUser($db , $effectiveUserID , $setTmpl ) };
601556
557+ if ($@ ) {
558+ $c -> log -> error(" Error creating test version of $setID for $effectiveUserID : $@ " );
559+ $c -> {invalidSet } =
560+ $c -> maketext(' Unable to generate a valid test version. This is usually caused by invalid '
561+ . ' usage of grouping sets or a database error. Please speak to your instructor to fix the '
562+ . ' error. A system administrator can obtain more details on this error from the logs.' );
563+ # Attempt to delete the set version if it was created. Failure from this attempt is ignored.
564+ eval { $db -> deleteSetVersion($userID , $setID , $setVersionNumber + 1) }
565+ if $db -> existsSetVersion($userID , $setID , $setVersionNumber + 1);
566+ } else {
567+ # Get the right name, version number, etc., and redefine the
568+ # $set and $problem for the remainder of this method.
569+
570+ ++$setVersionNumber ;
571+
572+ # Get a clean version of the set and merged version to use in the rest of the routine.
573+ my $cleanSet = $db -> getSetVersion($effectiveUserID , $setID , $setVersionNumber );
574+ $set = $db -> getMergedSetVersion($effectiveUserID , $setID , $setVersionNumber );
575+ $set -> visible(1);
576+
577+ $problem = $db -> getMergedProblemVersion($effectiveUserID , $setID , $setVersionNumber , $setPNum [0]);
578+
579+ # Convert the floating point value from Time::HiRes to an integer for use below. Truncate toward 0.
580+ my $timeNowInt = int ($c -> submitTime);
581+
582+ # Set up creation time, and open and due dates.
583+ my $ansOffset = $set -> answer_date - $set -> due_date;
584+ $set -> version_creation_time($timeNowInt );
585+ $set -> open_date($timeNowInt );
586+ # Figure out the due date, taking into account the time limit cap.
587+ my $dueTime =
588+ $timeLimit == 0 || ($set -> time_limit_cap && $c -> submitTime + $timeLimit > $set -> due_date)
589+ ? $set -> due_date
590+ : $timeNowInt + $timeLimit ;
591+
592+ $set -> due_date($dueTime );
593+ $set -> answer_date($set -> due_date + $ansOffset );
594+ $set -> version_last_attempt_time(0);
595+
596+ # Put this new info into the database. Put back the data needed for the version, and leave blank
597+ # any information that should be inherited from the user set or global set. Set the data which
598+ # determines if a set is open, because a set version should not reopen after it's complete.
599+ $cleanSet -> version_creation_time($set -> version_creation_time);
600+ $cleanSet -> open_date($set -> open_date);
601+ $cleanSet -> due_date($set -> due_date);
602+ $cleanSet -> answer_date($set -> answer_date);
603+ $cleanSet -> version_last_attempt_time($set -> version_last_attempt_time);
604+ $cleanSet -> version_time_limit($set -> version_time_limit);
605+ $cleanSet -> attempts_per_version($set -> attempts_per_version);
606+ $cleanSet -> assignment_type($set -> assignment_type);
607+ $db -> putSetVersion($cleanSet );
608+
609+ # This is a new set version, so it's open.
610+ $versionIsOpen = 1;
611+
612+ # Set the number of attempts for this set to zero.
613+ $currentNumAttempts = 0;
614+ }
602615 } elsif ($maxAttempts != -1 && $totalNumVersions > $maxAttempts ) {
603616 $c -> {invalidSet } = $c -> maketext(' No new versions of this test are available, '
604617 . ' because you have already taken the maximum number allowed.' );
0 commit comments