/**
  * Convert data attribute to a string
  *
  * @param \core_renderer $output
  * @return string
  */
 protected function data_to_string(\core_renderer $output)
 {
     if ($this->data instanceof \Exception) {
         $info = get_exception_info($this->data);
         return $output->fatal_error($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo);
     } else {
         return json_encode($this->data);
     }
 }
Example #2
0
 /**
  * Silent exception handler.
  *
  * @return callable exception handler
  */
 public static function get_exception_handler()
 {
     return function ($ex) {
         $info = get_exception_info($ex);
         $logerrmsg = "enrol_paypal IPN exception handler: " . $info->message;
         if (debugging('', DEBUG_NORMAL)) {
             $logerrmsg .= ' Debug: ' . $info->debuginfo . "\n" . format_backtrace($info->backtrace, true);
         }
         error_log($logerrmsg);
         exit(0);
     };
 }
Example #3
0
/**
 * upgrade logging functions
 */
function upgrade_handle_exception($ex, $plugin = null) {
    global $CFG;

    // rollback everything, we need to log all upgrade problems
    abort_all_db_transactions();

    $info = get_exception_info($ex);

    // First log upgrade error
    upgrade_log(UPGRADE_LOG_ERROR, $plugin, 'Exception: ' . get_class($ex), $info->message, $info->backtrace);

    // Always turn on debugging - admins need to know what is going on
    set_debugging(DEBUG_DEVELOPER, true);

    default_exception_handler($ex, true, $plugin);
}
function judge_all_unjudged()
{
    while ($task = get_one_unjudged_task()) {
        verbose(cli_heading('TASK: ' . $task->id, true));
        verbose('Judging...');
        try {
            $task = onlinejudge_judge($task);
            verbose("Successfully judged: {$task->status}");
        } catch (Exception $e) {
            $info = get_exception_info($e);
            $errmsg = "Judged inner level exception handler: " . $info->message . ' Debug: ' . $info->debuginfo . "\n" . format_backtrace($info->backtrace, true);
            cli_problem($errmsg);
            // Continue to get next unjudged task
        }
    }
}
Example #5
0
 /**
  * Call an external function validating all params/returns correctly.
  *
  * Note that an external function may modify the state of the current page, so this wrapper
  * saves and restores tha PAGE and COURSE global variables before/after calling the external function.
  *
  * @param string $function A webservice function name.
  * @param array $args Params array (named params)
  * @param boolean $ajaxonly If true, an extra check will be peformed to see if ajax is required.
  * @return array containing keys for error (bool), exception and data.
  */
 public static function call_external_function($function, $args, $ajaxonly = false)
 {
     global $PAGE, $COURSE, $CFG, $SITE;
     require_once $CFG->libdir . "/pagelib.php";
     $externalfunctioninfo = self::external_function_info($function);
     $currentpage = $PAGE;
     $currentcourse = $COURSE;
     $response = array();
     try {
         // Taken straight from from setup.php.
         if (!empty($CFG->moodlepageclass)) {
             if (!empty($CFG->moodlepageclassfile)) {
                 require_once $CFG->moodlepageclassfile;
             }
             $classname = $CFG->moodlepageclass;
         } else {
             $classname = 'moodle_page';
         }
         $PAGE = new $classname();
         $COURSE = clone $SITE;
         if ($ajaxonly && !$externalfunctioninfo->allowed_from_ajax) {
             throw new moodle_exception('servicenotavailable', 'webservice');
         }
         // Do not allow access to write or delete webservices as a public user.
         if ($externalfunctioninfo->loginrequired) {
             if (defined('NO_MOODLE_COOKIES') && NO_MOODLE_COOKIES && !PHPUNIT_TEST) {
                 throw new moodle_exception('servicenotavailable', 'webservice');
             }
             if (!isloggedin()) {
                 throw new moodle_exception('servicenotavailable', 'webservice');
             } else {
                 require_sesskey();
             }
         }
         // Validate params, this also sorts the params properly, we need the correct order in the next part.
         $callable = array($externalfunctioninfo->classname, 'validate_parameters');
         $params = call_user_func($callable, $externalfunctioninfo->parameters_desc, $args);
         // Execute - gulp!
         $callable = array($externalfunctioninfo->classname, $externalfunctioninfo->methodname);
         $result = call_user_func_array($callable, array_values($params));
         // Validate the return parameters.
         if ($externalfunctioninfo->returns_desc !== null) {
             $callable = array($externalfunctioninfo->classname, 'clean_returnvalue');
             $result = call_user_func($callable, $externalfunctioninfo->returns_desc, $result);
         }
         $response['error'] = false;
         $response['data'] = $result;
     } catch (Exception $e) {
         $exception = get_exception_info($e);
         unset($exception->a);
         if (!debugging('', DEBUG_DEVELOPER)) {
             unset($exception->debuginfo);
             unset($exception->backtrace);
         }
         $response['error'] = true;
         $response['exception'] = $exception;
         // Do not process the remaining requests.
     }
     $PAGE = $currentpage;
     $COURSE = $currentcourse;
     return $response;
 }
Example #6
0
/**
 * Extend the LTI services through the ltisource plugins
 *
 * @param stdClass $data LTI request data
 * @return bool
 * @throws coding_exception
 */
function lti_extend_lti_services($data)
{
    $plugins = get_plugin_list_with_function('ltisource', $data->messagetype);
    if (!empty($plugins)) {
        try {
            // There can only be one
            if (count($plugins) > 1) {
                throw new coding_exception('More than one ltisource plugin handler found');
            }
            $callback = current($plugins);
            call_user_func($callback, $data);
        } catch (moodle_exception $e) {
            $error = $e->getMessage();
            if (debugging('', DEBUG_DEVELOPER)) {
                $error .= ' ' . format_backtrace(get_exception_info($e)->backtrace);
            }
            $responsexml = lti_get_response_xml('failure', $error, $data->messageid, $data->messagetype);
            header('HTTP/1.0 400 bad request');
            echo $responsexml->asXML();
        }
        return true;
    }
    return false;
}
Example #7
0
/**
 * Log an LTI response.
 *
 * @param string $responsexml The response XML
 * @param Exception $e If there was an exception, pass that too
 */
function lti_log_response($responsexml, $e = null)
{
    if ($tempdir = make_temp_directory('mod_lti', false)) {
        if ($tempfile = tempnam($tempdir, 'mod_lti_response' . date('YmdHis'))) {
            $content = '';
            if ($e instanceof Exception) {
                $info = get_exception_info($e);
                $content .= "Exception:\n";
                $content .= "Message: {$info->message}\n";
                $content .= "Debug info: {$info->debuginfo}\n";
                $content .= "Backtrace:\n";
                $content .= format_backtrace($info->backtrace, true);
                $content .= "\n";
            }
            $content .= "Response XML:\n";
            $content .= $responsexml;
            file_put_contents($tempfile, $content);
            chmod($tempfile, 0644);
        }
    }
}
function RWSEHdlr($r_ex)
{
    abort_all_db_transactions();
    $r_inf = get_exception_info($r_ex);
    $r_msg = "\r\n-- Exception occurred --";
    $r_msg .= "\r\nmessage: {$r_inf->message}";
    $r_msg .= "\r\nerrorcode: {$r_inf->errorcode}";
    $r_msg .= "\r\nfile: " . $r_ex->getFile();
    $r_msg .= "\r\nline: " . $r_ex->getLine();
    $r_msg .= "\r\nlink: {$r_inf->link}";
    $r_msg .= "\r\nmoreinfourl: {$r_inf->moreinfourl}";
    $r_msg .= "\r\na: {$r_inf->a}";
    $r_msg .= "\r\ndebuginfo: {$r_inf->debuginfo}\r\n";
    RWSELog($r_msg);
    RWSELog("\r\nstacktrace: " . $r_ex->getTraceAsString());
    RWSSErr("2112,{$r_inf->errorcode}");
}
 /**
  * Echo an exception message encapsulated in XML.
  *
  * @param \Exception $exception The exception that was thrown
  */
 public function handle(\Exception $exception)
 {
     $message = $exception->getMessage();
     // Add the exception backtrace for developers.
     if (debugging('', DEBUG_DEVELOPER)) {
         $message .= "\n" . format_backtrace(get_exception_info($exception)->backtrace, true);
     }
     // Switch to response.
     $type = str_replace('Request', 'Response', $this->type);
     // Build the appropriate xml.
     $response = lti_get_response_xml('failure', $message, $this->id, $type);
     $xml = $response->asXML();
     // Log the request if necessary.
     if ($this->log) {
         lti_log_response($xml, $exception);
     }
     echo $xml;
 }
 /**
  * Test if get_exception_info() removes file system paths.
  */
 public function test_exception_info_removes_serverpaths()
 {
     global $CFG;
     // This doesn't test them all possible ones, but these are set for unit tests.
     $cfgnames = array('dataroot', 'dirroot', 'tempdir', 'cachedir', 'localcachedir');
     $fixture = '';
     $expected = '';
     foreach ($cfgnames as $cfgname) {
         if (!empty($CFG->{$cfgname})) {
             $fixture .= $CFG->{$cfgname} . ' ';
             $expected .= "[{$cfgname}] ";
         }
     }
     $exception = new moodle_exception('generalexceptionmessage', 'error', '', $fixture, $fixture);
     $exceptioninfo = get_exception_info($exception);
     $this->assertContains($expected, $exceptioninfo->message, 'Exception message does not contain system paths');
     $this->assertContains($expected, $exceptioninfo->debuginfo, 'Exception debug info does not contain system paths');
 }
Example #11
0
        // Do not allow access to write or delete webservices as a public user.
        if ($externalfunctioninfo->loginrequired) {
            if (!isloggedin()) {
                error_log('This external function is not available to public users. Failed to call "' . $methodname . '"');
                throw new moodle_exception('servicenotavailable', 'webservice');
            }
        }
        // Validate params, this also sorts the params properly, we need the correct order in the next part.
        $callable = array($externalfunctioninfo->classname, 'validate_parameters');
        $params = call_user_func($callable, $externalfunctioninfo->parameters_desc, $args);
        // Execute - gulp!
        $callable = array($externalfunctioninfo->classname, $externalfunctioninfo->methodname);
        $result = call_user_func_array($callable, array_values($params));
        $response['error'] = false;
        $response['data'] = $result;
        $responses[$index] = $response;
    } catch (Exception $e) {
        $jsonexception = get_exception_info($e);
        unset($jsonexception->a);
        if (!debugging('', DEBUG_DEVELOPER)) {
            unset($jsonexception->debuginfo);
            unset($jsonexception->backtrace);
        }
        $response['error'] = true;
        $response['exception'] = $jsonexception;
        $responses[$index] = $response;
        // Do not process the remaining requests.
        break;
    }
}
echo json_encode($responses);
Example #12
0
/**
 * Silent exception handler.
 *
 * @param Exception $ex
 * @return void - does not return. Terminates execution!
 */
function mod_paypal_ipn_exception_handler($ex)
{
    $info = get_exception_info($ex);
    $logerrmsg = "mod_paypal IPN exception handler: " . $info->message;
    if (debugging('', DEBUG_NORMAL)) {
        $logerrmsg .= ' Debug: ' . $info->debuginfo . "\n" . format_backtrace($info->backtrace, true);
    }
    error_log($logerrmsg);
    exit(0);
}
Example #13
0
function lockdownbrowser_MonitorExceptionHandler($ex)
{
    abort_all_db_transactions();
    $info = get_exception_info($ex);
    $msg = "\r\n-- Exception occurred --" . "\r\nmessage: {$info->message}" . "\r\nerrorcode: {$info->errorcode}" . "\r\nbacktrace: {$info->backtrace}" . "\r\nlink: {$info->link}" . "\r\nmoreinfourl: {$info->moreinfourl}" . "\r\na: {$info->a}" . "\r\ndebuginfo: {$info->debuginfo}\r\n";
    lockdownbrowser_MonitorLog($msg);
    lockdownbrowser_MonitorLog("\r\nstacktrace: " . $ex->getTraceAsString());
    lockdownbrowser_MonitorServiceError(2003, "A Moodle or PHP server exception occurred: {$info->errorcode}");
}
Example #14
0
 /**
  * Wrapper to call {@link get_exception_info()}.
  *
  * @param  Exception $ex An exception.
  * @return stdClass of information.
  */
 public function get_exception_info($ex)
 {
     try {
         throw $ex;
     } catch (moodle_exception $e) {
         return get_exception_info($e);
     }
 }
 /**
  * Adds and upgrades the selected plugins
  *
  * @param array $ingredients
  * @param string $path Path to the ingredient type file system
  * @param SimpleXMLElement $xml
  * @return array Problems during the ingredients deployment
  */
 public function deploy_ingredients($ingredients, $path, SimpleXMLElement $xml)
 {
     // Using the $ingredients array keys to maintain coherence with the main deployment method
     $problems = array();
     $pluginman = plugin_manager::instance();
     $plugintypespaths = get_plugin_types();
     $this->get_flavour_info($xml);
     foreach ($ingredients as $selection) {
         // [0] => ingredienttype, [1] => ingredientname
         $ingredientdata = explode('/', $selection);
         $type = $ingredientdata[0];
         $ingredient = $ingredientdata[1];
         if (empty($this->branches[$type]->branches[$ingredient])) {
             $problems[$selection]['pluginnotfound'] = $selection;
             continue;
         }
         $ingredientdata = $this->branches[$type]->branches[$ingredient];
         // Adapter to the restrictions array
         if (!empty($ingredientdata->restrictions)) {
             $problems[$selection] = $ingredientdata->restrictions;
             continue;
         }
         if (empty($xml->{$type}) || empty($xml->{$type}->{$ingredient})) {
             $problems[$selection]['pluginnotfound'] = $selection;
             continue;
         }
         // Deploy then
         $ingredientpath = $plugintypespaths[$type] . '/' . $ingredient;
         // Remove old dir if present
         if (file_exists($ingredientpath)) {
             // Report if the old plugin directory can't be removed
             if (!$this->unlink($ingredientpath)) {
                 $problems[$selection]['plugincantremove'] = $selection;
                 continue;
             }
         }
         // Copy the new contents where the flavour says
         $tmppath = $path . '/' . $xml->{$type}->{$ingredient}->path;
         if (!$this->copy($tmppath, $ingredientpath)) {
             debugging('From : ' . $tmppath . ' To: ' . $ingredientpath);
             $problems[$selection]['plugincopyerror'] = $selection;
         }
     }
     // Execute the moodle upgrade process
     try {
         foreach ($plugintypespaths as $type => $location) {
             upgrade_plugins($type, 'flavours_print_upgrade_void', 'flavours_print_upgrade_void', false);
         }
     } catch (Exception $ex) {
         abort_all_db_transactions();
         $info = get_exception_info($ex);
         upgrade_log(UPGRADE_LOG_ERROR, $ex->module, 'Exception: ' . get_class($ex), $info->message, $info->backtrace);
     }
     return $problems;
 }
Example #16
0
/**
 * Default exception handler, uncaught exceptions are equivalent to error() in 1.9 and earlier
 *
 * @param Exception $ex
 * @return void -does not return. Terminates execution!
 */
function default_exception_handler($ex)
{
    global $CFG, $DB, $OUTPUT, $USER, $FULLME, $SESSION, $PAGE;
    // detect active db transactions, rollback and log as error
    abort_all_db_transactions();
    if ($ex instanceof required_capability_exception && !CLI_SCRIPT && !AJAX_SCRIPT && !empty($CFG->autologinguests) && !empty($USER->autologinguest)) {
        $SESSION->wantsurl = qualified_me();
        redirect(get_login_url());
    }
    $info = get_exception_info($ex);
    if (debugging('', DEBUG_MINIMAL)) {
        $logerrmsg = "Default exception handler: " . $info->message . ' Debug: ' . $info->debuginfo . "\n" . format_backtrace($info->backtrace, true);
        error_log($logerrmsg);
    }
    if (is_early_init($info->backtrace)) {
        echo bootstrap_renderer::early_error($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo, $info->errorcode);
    } else {
        try {
            if ($DB) {
                // If you enable db debugging and exception is thrown, the print footer prints a lot of rubbish
                $DB->set_debug(0);
            }
            echo $OUTPUT->fatal_error($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo);
        } catch (Exception $out_ex) {
            // default exception handler MUST not throw any exceptions!!
            // the problem here is we do not know if page already started or not, we only know that somebody messed up in outputlib or theme
            // so we just print at least something instead of "Exception thrown without a stack frame in Unknown on line 0":-(
            if (CLI_SCRIPT or AJAX_SCRIPT) {
                // just ignore the error and send something back using the safest method
                echo bootstrap_renderer::early_error($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo, $info->errorcode);
            } else {
                echo bootstrap_renderer::early_error_content($info->message, $info->moreinfourl, $info->link, $info->backtrace, $info->debuginfo);
                $outinfo = get_exception_info($out_ex);
                echo bootstrap_renderer::early_error_content($outinfo->message, $outinfo->moreinfourl, $outinfo->link, $outinfo->backtrace, $outinfo->debuginfo);
            }
        }
    }
    exit(1);
    // General error code
}
Example #17
0
function xmldb_block_lockdownbrowser_install()
{
    global $DB;
    global $CFG;
    $enable_log = FALSE;
    // set TRUE to enable logging to temp file
    $install_log = "ldb_install.log";
    $warning_settings = "<p>lockdownbrowser block install warning: could not migrate quiz settings from legacy lockdown module</p>";
    $warning_files = "<p>lockdownbrowser block install warning: could not undo changes to quiz module made by legacy lockdown module</p>";
    $block_settings_table = "block_lockdownbrowser_sett";
    $module_settings_table = "lockdown_settings";
    $quiz_table = "quiz";
    $quiz_file = "{$CFG->dirroot}/mod/quiz/attempt.php";
    $quiz_module_folder = "{$CFG->dirroot}/mod/quiz";
    $quiz_backup_folders = "{$CFG->dataroot}/lockdownquiz-[0-1][0-9][0-3][0-9]-[0-1][0-9][0-5][0-9]/backup";
    if ($CFG->version >= 2011120500.0) {
        // Moodle 2.2
        $quiz_backup_files = array("attempt.php", "lib.php", "mod_form.php", "review.php", "view.php", "accessmanager.php");
    } else {
        $quiz_backup_files = array("accessrules.php", "attempt.php", "lib.php", "mod_form.php", "review.php");
    }
    $debug_info = "* start: " . date("m-d-Y H:i:s") . "\r\n";
    $exception_msg = "";
    $migrate_settings = FALSE;
    $undo_quiz_changes = FALSE;
    try {
        $debug_info .= "* migrating settings from legacy ldb module to ldb block\r\n";
        $ok = TRUE;
        $dbman = $DB->get_manager();
        $table = new xmldb_table($module_settings_table);
        $migrate_settings = $dbman->table_exists($table);
        if (!$migrate_settings) {
            $debug_info .= "* no need to migrate settings: table {$module_settings_table} does not exist\r\n";
        }
        if ($migrate_settings) {
            $table = new xmldb_table($block_settings_table);
            $ok = $dbman->table_exists($table);
            if (!$ok) {
                $debug_info .= "* error: table {$block_settings_table} does not exist\r\n";
            }
        }
        if ($migrate_settings && $ok) {
            $records = $DB->get_records($module_settings_table);
            $ok = $records !== FALSE || count($records) != 0;
            if (!$ok) {
                $debug_info .= "* error: table {$module_settings_table} has no records\r\n";
            }
        }
        if ($migrate_settings && $ok) {
            foreach ($records as $modset) {
                if ($modset->attempts == 0 && $modset->reviews == 0) {
                    continue;
                }
                // not LDB quiz, nothing to migrate
                $quiz = $DB->get_record($quiz_table, array("id" => $modset->quizid));
                if ($quiz === FALSE) {
                    continue;
                }
                // quiz gone, no need to migrate
                $blkset = $DB->get_record($block_settings_table, array("quizid" => $quiz->id));
                if ($blkset !== FALSE) {
                    continue;
                }
                // quiz settings already migrated
                $blkset = new stdClass();
                $blkset->course = $quiz->course;
                $blkset->quizid = $quiz->id;
                $blkset->attempts = 0;
                $blkset->reviews = 0;
                $blkset->password = $modset->password;
                $blkset->monitor = "";
                $ok = $DB->insert_record($block_settings_table, $blkset);
                if (!$ok) {
                    $debug_info .= "* error: could not insert record into table {$block_settings_table}\r\n";
                    break;
                }
            }
        }
        if ($migrate_settings && $ok) {
            $debug_info .= "* settings migration succeeded\r\n";
        }
    } catch (Exception $e) {
        $info = get_exception_info($e);
        $msg = "\r\nmessage: {$info->message}" . "\r\nerrorcode: {$info->errorcode}" . "\r\nbacktrace: {$info->backtrace}" . "\r\nlink: {$info->link}" . "\r\nmoreinfourl: {$info->moreinfourl}" . "\r\na: {$info->a}" . "\r\ndebuginfo: {$info->debuginfo}\r\n" . "\r\nstacktrace: " . $e->getTraceAsString();
        $debug_info .= "* exception occurred: {$msg}\r\n";
        $ok = FALSE;
    }
    if ($migrate_settings && !$ok) {
        $exception_msg .= $warning_settings;
    }
    try {
        $debug_info .= "* restoring file changes made to quiz module by legacy ldb module\r\n";
        if (false) {
            $undo_quiz_changes = TRUE;
        } else {
            if (is_readable($quiz_file)) {
                $contents = file_get_contents($quiz_file);
                if ($contents !== FALSE) {
                    $pos = strpos($contents, "## LockDown");
                    $undo_quiz_changes = $pos !== FALSE;
                }
            }
        }
        if (!$undo_quiz_changes) {
            $debug_info .= "* no need to restore file changes: could not find edit marker string\r\n";
        }
        if ($undo_quiz_changes) {
            $folders = glob($quiz_backup_folders, GLOB_ONLYDIR);
            $ok = is_array($folders) && count($folders) > 0 && strlen($folders[0]) > 0;
            if (!$ok) {
                $debug_info .= "* error: could not find quiz backup folder\r\n";
            }
        }
        if ($undo_quiz_changes && $ok) {
            if (count($folders) == 1) {
                $src_folder = $folders[0];
            } else {
                // find most recent folder
                $latest_time = 0;
                $latest_path = "";
                foreach ($folders as $path) {
                    $time = filectime($path);
                    $ok = $time !== FALSE;
                    if (!$ok) {
                        $debug_info .= "* error: could not determine which quiz backup folder to use\r\n";
                        break;
                    }
                    if ($time > $latest) {
                        $latest_time = $time;
                        $latest_path = $path;
                    }
                }
                if ($ok) {
                    $src_folder = $latest_path;
                    $debug_info .= "* restoring from quiz backup folder {$src_folder}\r\n";
                }
            }
        }
        if ($undo_quiz_changes && $ok) {
            $dest_folder = $quiz_module_folder;
            $ok = is_dir($dest_folder);
            if (!$ok) {
                $debug_info .= "* error: could not find quiz module folder {$dest_folder}\r\n";
            }
        }
        if ($undo_quiz_changes && $ok) {
            foreach ($quiz_backup_files as $file) {
                $ok2 = copy("{$src_folder}/{$file}", "{$dest_folder}/{$file}");
                if (!$ok2) {
                    $ok = FALSE;
                    $debug_info .= "* error: could not copy {$file} from {$src_folder} to {$dest_folder}\r\n";
                }
            }
        }
        if ($undo_quiz_changes && $ok) {
            $debug_info .= "* restoring file changes succeeded\r\n";
        }
    } catch (Exception $e) {
        $info = get_exception_info($e);
        $msg = "\r\nmessage: {$info->message}" . "\r\nerrorcode: {$info->errorcode}" . "\r\nbacktrace: {$info->backtrace}" . "\r\nlink: {$info->link}" . "\r\nmoreinfourl: {$info->moreinfourl}" . "\r\na: {$info->a}" . "\r\ndebuginfo: {$info->debuginfo}\r\n" . "\r\nstacktrace: " . $e->getTraceAsString();
        $debug_info .= "* exception occurred: {$msg}\r\n";
        $ok = FALSE;
    }
    if ($undo_quiz_changes && !$ok) {
        $exception_msg .= $warning_files;
    }
    // write debug file
    $debug_info .= "* end\r\n";
    if ($enable_log) {
        if (isset($CFG->tempdir)) {
            $path = "{$CFG->tempdir}/{$install_log}";
        } else {
            $path = "{$CFG->dataroot}/temp/{$install_log}";
        }
        $handle = fopen($path, "wb");
        if ($handle !== FALSE) {
            fwrite($handle, $debug_info, strlen($debug_info));
            fclose($handle);
        }
    }
    // inform user if migration failed
    if (strlen($exception_msg) > 0) {
        throw new moodle_exception($exception_msg, "block_lockdownbrowser");
    }
}