function site_error_handler($errno, $errstr, $errfile, $errline) { $today = date("D M j G:i:s T Y"); if (isset($GLOBALS['CONFIG']['error_log']) && is_file($GLOBALS['CONFIG']['error_log']) && is_writeable($GLOBALS['CONFIG']['error_log'])) { $error_log_avail = TRUE; } else { error_log("sure_invoice: Could not write to error log: " . $GLOBALS['CONFIG']['error_log'], 0); $error_log_avail = FALSE; } // Log the error if ($error_log_avail && $errno != E_NOTICE) { error_log("{$today}: PHP Error ({$errno}): {$errstr} in {$errfile} at {$errline}.\n", 3, $GLOBALS['CONFIG']['error_log']); } // Email error if (isset($GLOBALS['CONFIG']['error_email']) && $errno != E_NOTICE && $errno != E_USER_NOTICE) { error_log("{$_SERVER['SERVER_NAME']} Server Error\n\n{$today}: PHP Error ({$errno}): {$errstr} in {$errfile} at {$errline}.\n", 1, $APP_GLOBALS['ERROR_EMAIL']); } // If it is an error redirect to error page or print message if ($errno == E_COMPILE_ERROR || $errno == E_CORE_ERROR || $errno == E_USER_ERROR || $errno == E_ERROR) { if ($GLOBALS['CONFIG']['debug']) { $error_msg = "<PRE>PHP Error ({$errno}): {$errfile} at {$errline}.\n\n{$errstr}\n\n\n" . format_backtrace(debug_backtrace()) . "\n\n</PRE>"; } else { $error_msg = "We are sorry, an error has occured while processing your request, please try again later.\n" . "The system administrator has been notified of the problem.\n"; } fatal_error($error_msg); } }
/** * 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); }; }
/** * mDebug_log * * @param mix $mix * @param string $msg * @param int $level * @return boolean */ function mDebug_log($mix, $msg = '', $level = DEBUG_NORMAL) { global $USER, $CFG; try { if (!useMDebug($level)) { return false; } if (is_object($mix) || is_array($mix)) { if (is_object($mix)) { $info = "Object " . get_class($mix) . " >> "; } elseif (is_array($mix)) { $info = "Array >> "; } $print = print_r((array) $mix, true); $print = substr($print, strpos($print, '(')); $info .= $print; $info = substr($info, 0, strlen($info) - 1); } else { $info = gettype($mix) . " >> {$mix} \n"; } $from = ""; if ($CFG->mDebugBacktrace === true) { $backtrace = debug_backtrace(); $from = format_backtrace($backtrace, true); } if (empty($msg)) { error_log(time() . ' : ' . $info . ' : ' . $from, 3, $CFG->dataroot . '/mdebug.log'); } else { error_log(time() . ' : ' . $msg . ' : ' . $info . ' : ' . $from, 3, $CFG->dataroot . '/mdebug.log'); } return true; } catch (Exception $e) { error_log(time() . ' : FALHA NO DEBUG >> $e : ' . $from, 3, $CFG->dataroot . '/mdebug.log'); return false; } }
function ttrss_fatal_handler() { global $logger; global $last_query; $error = error_get_last(); if ($error !== NULL) { $errno = $error["type"]; $file = $error["file"]; $line = $error["line"]; $errstr = $error["message"]; if (!$errno) { return false; } $context = format_backtrace(debug_backtrace()); $file = substr(str_replace(dirname(dirname(__FILE__)), "", $file), 1); if ($last_query) { $errstr .= " [Last query: {$last_query}]"; } if (class_exists("Logger")) { return Logger::get()->log_error($errno, $errstr, $file, $line, $context); } } return false; }
/** * Standard Debugging Function * * Returns true if the current site debugging settings are equal or above specified level. * If passed a parameter it will emit a debugging notice similar to trigger_error(). The * routing of notices is controlled by $CFG->debugdisplay * eg use like this: * * 1) debugging('a normal debug notice'); * 2) debugging('something really picky', DEBUG_ALL); * 3) debugging('annoying debug message only for developers', DEBUG_DEVELOPER); * 4) if (debugging()) { perform extra debugging operations (do not use print or echo) } * * In code blocks controlled by debugging() (such as example 4) * any output should be routed via debugging() itself, or the lower-level * trigger_error() or error_log(). Using echo or print will break XHTML * JS and HTTP headers. * * It is also possible to define NO_DEBUG_DISPLAY which redirects the message to error_log. * * @uses DEBUG_NORMAL * @param string $message a message to print * @param int $level the level at which this debugging statement should show * @param array $backtrace use different backtrace * @return bool */ function debugging($message = '', $level = DEBUG_NORMAL, $backtrace = null) { global $CFG, $USER, $UNITTEST; $forcedebug = false; if (!empty($CFG->debugusers)) { $debugusers = explode(',', $CFG->debugusers); $forcedebug = in_array($USER->id, $debugusers); } if (!$forcedebug and empty($CFG->debug) || $CFG->debug < $level) { return false; } if (!isset($CFG->debugdisplay)) { $CFG->debugdisplay = ini_get_bool('display_errors'); } if ($message) { if (!$backtrace) { $backtrace = debug_backtrace(); } $from = format_backtrace($backtrace, CLI_SCRIPT); if (!empty($UNITTEST->running)) { // When the unit tests are running, any call to trigger_error // is intercepted by the test framework and reported as an exception. // Therefore, we cannot use trigger_error during unit tests. // At the same time I do not think we should just discard those messages, // so displaying them on-screen seems like the only option. (MDL-20398) echo '<div class="notifytiny">' . $message . $from . '</div>'; } else { if (NO_DEBUG_DISPLAY) { // script does not want any errors or debugging in output, // we send the info to error log instead error_log('Debugging: ' . $message . $from); } else { if ($forcedebug or $CFG->debugdisplay) { if (!defined('DEBUGGING_PRINTED')) { define('DEBUGGING_PRINTED', 1); // indicates we have printed something } if (CLI_SCRIPT) { echo "++ {$message} ++\n{$from}"; } else { echo '<div class="notifytiny">' . $message . $from . '</div>'; } } else { trigger_error($message . $from, E_USER_NOTICE); } } } } return true; }
/** * This logs the last query based on 'logall', 'logslow' and 'logerrors' options configured via $CFG->dboptions . * @param string|bool $error or false if not error * @return void */ public function query_log($error = false) { $logall = !empty($this->dboptions['logall']); $logslow = !empty($this->dboptions['logslow']) ? $this->dboptions['logslow'] : false; $logerrors = !empty($this->dboptions['logerrors']); $iserror = $error !== false; $time = $this->query_time(); // Will be shown or not depending on MDL_PERF values rather than in dboptions['log*]. $this->queriestime = $this->queriestime + $time; if ($logall or $logslow and $logslow < $time + 1.0E-5 or $iserror and $logerrors) { $this->loggingquery = true; try { $backtrace = debug_backtrace(); if ($backtrace) { //remove query_log() array_shift($backtrace); } if ($backtrace) { //remove query_end() array_shift($backtrace); } $log = new stdClass(); $log->qtype = $this->last_type; $log->sqltext = $this->last_sql; $log->sqlparams = var_export((array) $this->last_params, true); $log->error = (int) $iserror; $log->info = $iserror ? $error : null; $log->backtrace = format_backtrace($backtrace, true); $log->exectime = $time; $log->timelogged = time(); $this->insert_record('log_queries', $log); } catch (Exception $ignored) { } $this->loggingquery = false; } }
protected function ensure_theme_not_set() { if (!is_null($this->_theme)) { throw new coding_exception('The theme has already been set up for this page ready for output. ' . 'Therefore, you can no longer change the theme, or anything that might affect what ' . 'the current theme is, for example, the course.', 'Stack trace when the theme was set up: ' . format_backtrace($this->_wherethemewasinitialised)); } }
/** * Returns a template fragment representing a fatal error. * * @param string $message The message to output * @param string $moreinfourl URL where more info can be found about the error * @param string $link Link for the Continue button * @param array $backtrace The execution backtrace * @param string $debuginfo Debugging information * @return string A template fragment for a fatal error */ public function fatal_error($message, $moreinfourl, $link, $backtrace, $debuginfo = null) { global $CFG; $this->page->set_context(null); // ugly hack - make sure page context is set to something, we do not want bogus warnings here $e = new stdClass(); $e->error = $message; $e->stacktrace = NULL; $e->debuginfo = NULL; $e->reproductionlink = NULL; if (!empty($CFG->debug) and $CFG->debug >= DEBUG_DEVELOPER) { $link = (string) $link; if ($link) { $e->reproductionlink = $link; } if (!empty($debuginfo)) { $e->debuginfo = $debuginfo; } if (!empty($backtrace)) { $e->stacktrace = format_backtrace($backtrace, true); } } $this->header(); return json_encode($e); }
function dprint($file, $line, $level, $msg) { global $dPconfig; $max_level = 0; $max_level = (int) $dPconfig['debug']; $display_debug = isset($dPconfig['display_debug']) ? $dPconfig['display_debug'] : false; if ($level <= $max_level) { error_log("{$file}({$line}): {$msg}"); if ($display_debug) { echo "{$file}({$line}): {$msg} <br />"; } if ($level == 0 && $max_level > 0 && version_compare(phpversion(), "4.3.0") >= 0) { format_backtrace(debug_backtrace(), $file, $line, $msg); } } }
/** * given a queued handler, call the respective event handler to process the event * * @access protected To be used from eventslib only * @deprecated since Moodle 3.1 * @param stdClass $qhandler events_queued_handler row from db * @return boolean true means event processed, false means retry later, NULL means fatal failure */ function events_process_queued_handler($qhandler) { global $DB; // get handler if (!($handler = $DB->get_record('events_handlers', array('id' => $qhandler->handlerid)))) { debugging("Error processing queue handler {$qhandler->id}, missing handler id: {$qhandler->handlerid}"); //irrecoverable error, remove broken queue handler events_dequeue($qhandler); return NULL; } // get event object if (!($event = $DB->get_record('events_queue', array('id' => $qhandler->queuedeventid)))) { // can't proceed with no event object - might happen when two crons running at the same time debugging("Error processing queue handler {$qhandler->id}, missing event id: {$qhandler->queuedeventid}"); //irrecoverable error, remove broken queue handler events_dequeue($qhandler); return NULL; } // call the function specified by the handler try { $errormessage = 'Unknown error'; if (events_dispatch($handler, unserialize(base64_decode($event->eventdata)), $errormessage)) { //everything ok events_dequeue($qhandler); return true; } } catch (Exception $e) { // the problem here is that we do not want one broken handler to stop all others, // cron handlers are very tricky because the needed data might have been deleted before the cron execution $errormessage = "Handler function of component {$handler->component}: {$handler->handlerfunction} threw exception :" . $e->getMessage() . "\n" . format_backtrace($e->getTrace(), true); if (!empty($e->debuginfo)) { $errormessage .= $e->debuginfo; } } //dispatching failed $qh = new stdClass(); $qh->id = $qhandler->id; $qh->errormessage = $errormessage; $qh->timemodified = time(); $qh->status = $qhandler->status + 1; $DB->update_record('events_queue_handlers', $qh); debugging($errormessage); return false; }
/** * Log last database query if requested * @param mixed string error or false if not error * @return void */ public function query_log($error=false) { $logall = !empty($this->dboptions['logall']); $logslow = !empty($this->dboptions['logslow']) ? $this->dboptions['logslow'] : false; $logerrors = !empty($this->dboptions['logerrors']); $iserror = ($error !== false); $time = microtime(true) - $this->last_time; if ($logall or ($logslow and ($logslow < ($time+0.00001))) or ($iserror and $logerrors)) { $this->loggingquery = true; try { $backtrace = debug_backtrace(); if ($backtrace) { //remove query_log() array_shift($backtrace); } if ($backtrace) { //remove query_end() array_shift($backtrace); } $log = new stdClass(); $log->qtype = $this->last_type; $log->sqltext = $this->last_sql; $log->sqlparams = var_export((array)$this->last_params, true); $log->error = (int)$iserror; $log->info = $iserror ? $error : null; $log->backtrace = format_backtrace($backtrace, true); $log->exectime = $time; $log->timelogged = time(); $this->insert_record('log_queries', $log); } catch (Exception $ignored) { } $this->loggingquery = false; } }
/** * 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); } } }
try { get_mailer('buffer'); $task->execute(); if (isset($predbqueries)) { mtrace("... used " . ($DB->perf_get_queries() - $predbqueries) . " dbqueries"); mtrace("... used " . (microtime(1) - $pretime) . " seconds"); } mtrace("Task completed."); \core\task\manager::scheduled_task_complete($task); get_mailer('close'); exit(0); } catch (Exception $e) { if ($DB->is_transaction_started()) { $DB->force_transaction_rollback(); } mtrace("... used " . ($DB->perf_get_queries() - $predbqueries) . " dbqueries"); mtrace("... used " . (microtime(true) - $pretime) . " seconds"); mtrace("Task failed: " . $e->getMessage()); if ($CFG->debugdeveloper) { if (!empty($e->debuginfo)) { mtrace("Debug info:"); mtrace($e->debuginfo); } mtrace("Backtrace:"); mtrace(format_backtrace($e->getTrace(), true)); } \core\task\manager::scheduled_task_failed($task); get_mailer('close'); exit(1); } }
/** * Returns a template fragment representing a fatal error. * @param string $message The message to output * @param string $moreinfourl URL where more info can be found about the error * @param string $link Link for the Continue button * @param array $backtrace The execution backtrace * @param string $debuginfo Debugging information * @param bool $showerrordebugwarning Whether or not to show a debugging warning * @return string A template fragment for a fatal error */ public function fatal_error($message, $moreinfourl, $link, $backtrace, $debuginfo = null, $showerrordebugwarning = false) { $output = "!!! {$message} !!!\n"; if (debugging('', DEBUG_DEVELOPER)) { if (!empty($debuginfo)) { $this->notification($debuginfo, 'notifytiny'); } if (!empty($backtrace)) { $this->notification('Stack trace: ' . format_backtrace($backtrace, true), 'notifytiny'); } } }
/** * You should not need to call this constructor in your own code. Steps are * normally created by {@link question_attempt} methods like * {@link question_attempt::process_action()}. * @param array $data the submitted data that defines this step. * @param int $timestamp the time to record for the action. (If not given, use now.) * @param int $userid the user to attribute the aciton to. (If not given, use the current user.) * @param int $existingstepid if this step is going to replace an existing step * (for example, during a regrade) this is the id of the previous step we are replacing. */ public function __construct($data = array(), $timecreated = null, $userid = null, $existingstepid = null) { global $USER; if (!is_array($data)) { echo format_backtrace(debug_backtrace()); } $this->state = question_state::$unprocessed; $this->data = $data; if (is_null($timecreated)) { $this->timecreated = time(); } else { $this->timecreated = $timecreated; } if (is_null($userid)) { $this->userid = $USER->id; } else { $this->userid = $userid; } if (!is_null($existingstepid)) { $this->id = $existingstepid; } }
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 } } }
/** * Adds an entry to the log. * * @param string $action The name of the action * @param string $type The type of action */ protected function log($action, $type) { $this->log[] = '<li>' . $action . ' ' . $type . ' at:' . format_backtrace(debug_backtrace()) . '</li>'; }
function dprint($file, $line, $level, $msg) { $max_level = 0; $max_level = (int) w2PgetConfig('debug'); $display_debug = w2PgetConfig('display_debug', false); if ($level <= $max_level) { error_log($file . '(' . $line . '): ' . $msg); if ($display_debug) { echo $file . '(' . $line . '): ' . $msg . ' <br />'; } if ($level == 0 && $max_level > 0 && version_compare(phpversion(), '4.3.0') >= 0) { format_backtrace(debug_backtrace(), $file, $line, $msg); } } }
/** * Standard Debugging Function * * Returns true if the current site debugging settings are equal or above specified level. * If passed a parameter it will emit a debugging notice similar to trigger_error(). The * routing of notices is controlled by $CFG->debugdisplay * eg use like this: * * 1) debugging('a normal debug notice'); * 2) debugging('something really picky', DEBUG_ALL); * 3) debugging('annoying debug message only for developers', DEBUG_DEVELOPER); * 4) if (debugging()) { perform extra debugging operations (do not use print or echo) } * * In code blocks controlled by debugging() (such as example 4) * any output should be routed via debugging() itself, or the lower-level * trigger_error() or error_log(). Using echo or print will break XHTML * JS and HTTP headers. * * It is also possible to define NO_DEBUG_DISPLAY which redirects the message to error_log. * * @param string $message a message to print * @param int $level the level at which this debugging statement should show * @param array $backtrace use different backtrace * @return bool */ function debugging($message = '', $level = DEBUG_NORMAL, $backtrace = null) { global $CFG, $USER; $forcedebug = false; if (!empty($CFG->debugusers) && $USER) { $debugusers = explode(',', $CFG->debugusers); $forcedebug = in_array($USER->id, $debugusers); } if (!$forcedebug and empty($CFG->debug) || ($CFG->debug != -1 and $CFG->debug < $level)) { return false; } if (!isset($CFG->debugdisplay)) { $CFG->debugdisplay = ini_get_bool('display_errors'); } if ($message) { if (!$backtrace) { $backtrace = debug_backtrace(); } $from = format_backtrace($backtrace, CLI_SCRIPT || NO_DEBUG_DISPLAY); if (PHPUNIT_TEST) { if (phpunit_util::debugging_triggered($message, $level, $from)) { // We are inside test, the debug message was logged. return true; } } if (NO_DEBUG_DISPLAY) { // Script does not want any errors or debugging in output, // we send the info to error log instead. error_log('Debugging: ' . $message . ' in ' . PHP_EOL . $from); } else { if ($forcedebug or $CFG->debugdisplay) { if (!defined('DEBUGGING_PRINTED')) { define('DEBUGGING_PRINTED', 1); // Indicates we have printed something. } if (CLI_SCRIPT) { echo "++ {$message} ++\n{$from}"; } else { echo '<div class="notifytiny debuggingmessage" data-rel="debugging">', $message, $from, '</div>'; } } else { trigger_error($message . $from, E_USER_NOTICE); } } } return true; }
/** * 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; }
/** * Adds log entry into upgrade_log table * * @param int $type UPGRADE_LOG_NORMAL, UPGRADE_LOG_NOTICE or UPGRADE_LOG_ERROR * @param string $plugin frankenstyle component name * @param string $info short description text of log entry * @param string $details long problem description * @param string $backtrace string used for errors only * @return void */ function upgrade_log($type, $plugin, $info, $details=null, $backtrace=null) { global $DB, $USER, $CFG; if (empty($plugin)) { $plugin = 'core'; } list($plugintype, $pluginname) = core_component::normalize_component($plugin); $component = is_null($pluginname) ? $plugintype : $plugintype . '_' . $pluginname; $backtrace = format_backtrace($backtrace, true); $currentversion = null; $targetversion = null; //first try to find out current version number if ($plugintype === 'core') { //main $currentversion = $CFG->version; $version = null; include("$CFG->dirroot/version.php"); $targetversion = $version; } else { $pluginversion = get_config($component, 'version'); if (!empty($pluginversion)) { $currentversion = $pluginversion; } $cd = core_component::get_component_directory($component); if (file_exists("$cd/version.php")) { $plugin = new stdClass(); $plugin->version = null; $module = $plugin; include("$cd/version.php"); $targetversion = $plugin->version; } } $log = new stdClass(); $log->type = $type; $log->plugin = $component; $log->version = $currentversion; $log->targetversion = $targetversion; $log->info = $info; $log->details = $details; $log->backtrace = $backtrace; $log->userid = $USER->id; $log->timemodified = time(); try { $DB->insert_record('upgrade_log', $log); } catch (Exception $ignored) { // possible during install or 2.0 upgrade } }
function dprint($file, $line, $level, $msg) { $max_level = 0; $max_level = (int) dPgetConfig('debug'); $display_debug = dPgetConfig('display_debug', false); if ($level <= $max_level) { error_log("{$file}({$line}): {$msg}"); if ($display_debug) { echo "{$file}({$line}): {$msg} <br />"; } if ($level == 0 && $max_level > 0 && version_compare(phpversion(), "4.3.0") >= 0) { format_backtrace(debug_backtrace(), $file, $line, $msg); } } }
/** * Ensure the theme has not been loaded yet. If it has an exception is thrown. * * @throws coding_exception */ protected function ensure_theme_not_set() { // This is explicitly allowed for webservices though which may process many course contexts in a single request. if (WS_SERVER) { return; } if (!is_null($this->_theme)) { throw new coding_exception('The theme has already been set up for this page ready for output. ' . 'Therefore, you can no longer change the theme, or anything that might affect what ' . 'the current theme is, for example, the course.', 'Stack trace when the theme was set up: ' . format_backtrace($this->_wherethemewasinitialised)); } }
/** * Adds log entry into upgrade_log table * * @global object * @global object * @global object * @param int $type UPGRADE_LOG_NORMAL, UPGRADE_LOG_NOTICE or UPGRADE_LOG_ERROR * @param string $plugin plugin or null if main * @param string $info short description text of log entry * @param string $details long problem description * @param string $backtrace string used for errors only * @return void */ function upgrade_log($type, $plugin, $info, $details = null, $backtrace = null) { global $DB, $USER, $CFG; $plugin = $plugin === 'moodle' ? null : $plugin; $backtrace = format_backtrace($backtrace, true); $version = null; //first try to find out current version number if (empty($plugin) or $plugin === 'moodle') { //main $version = $CFG->version; } else { if ($plugin === 'local') { //customisation $version = $CFG->local_version; } else { if (strpos($plugin, 'mod/') === 0) { try { $modname = substr($plugin, strlen('mod/')); $version = $DB->get_field('modules', 'version', array('name' => $modname)); $version = $version === false ? null : $version; } catch (Exception $ignored) { } } else { if (strpos($plugin, 'block/') === 0) { try { $blockname = substr($plugin, strlen('block/')); if ($block = $DB->get_record('block', array('name' => $blockname))) { $version = $block->version; } } catch (Exception $ignored) { } } else { $pluginversion = get_config(str_replace('/', '_', $plugin), 'version'); if (!empty($pluginversion)) { $version = $pluginversion; } } } } } $log = new object(); $log->type = $type; $log->plugin = $plugin; $log->version = $version; $log->info = $info; $log->details = $details; $log->backtrace = $backtrace; $log->userid = $USER->id; $log->timemodified = time(); try { $DB->insert_record('upgrade_log', $log); } catch (Exception $ignored) { // possible during install or 2.0 upgrade } }
/** * Append YUI3 module to default YUI3 JS loader. * The structure of module array is described at {@link http://developer.yahoo.com/yui/3/yui/} * * @param string|array $module name of module (details are autodetected), or full module specification as array * @return void */ public function js_module($module) { global $CFG; if (empty($module)) { throw new coding_exception('Missing YUI3 module name or full description.'); } if (is_string($module)) { $module = $this->find_module($module); } if (empty($module) or empty($module['name']) or empty($module['fullpath'])) { throw new coding_exception('Missing YUI3 module details.'); } // Don't load this module if we already have, no need to! if ($this->js_module_loaded($module['name'])) { if (debugging('', DEBUG_DEVELOPER)) { $this->debug_moduleloadstacktraces[$module['name']][] = format_backtrace(debug_backtrace()); } return; } $module['fullpath'] = $this->js_fix_url($module['fullpath'])->out(false); // Add all needed strings. if (!empty($module['strings'])) { foreach ($module['strings'] as $string) { $identifier = $string[0]; $component = isset($string[1]) ? $string[1] : 'moodle'; $a = isset($string[2]) ? $string[2] : null; $this->string_for_js($identifier, $component, $a); } } unset($module['strings']); // Process module requirements and attempt to load each. This allows // moodle modules to require each other. if (!empty($module['requires'])) { foreach ($module['requires'] as $requirement) { $rmodule = $this->find_module($requirement); if (is_array($rmodule)) { $this->js_module($rmodule); } } } if ($this->headdone) { $this->extramodules[$module['name']] = $module; } else { $this->YUI_config->add_module_config($module['name'], $module); } if (debugging('', DEBUG_DEVELOPER)) { if (!array_key_exists($module['name'], $this->debug_moduleloadstacktraces)) { $this->debug_moduleloadstacktraces[$module['name']] = array(); } $this->debug_moduleloadstacktraces[$module['name']][] = format_backtrace(debug_backtrace()); } }
echo $controller->is_userdata_copyable($cmid); exit; case 'backup': $cmid = required_param('cmid', PARAM_INT); $userdata = required_param('userdata', PARAM_BOOL); $controller->backup($cmid, $userdata); exit; case 'movedir': $id = required_param('id', PARAM_INT); $to = required_param('to', PARAM_TEXT); $controller->movedir($id, $to); exit; case 'move': $id = required_param('id', PARAM_INT); $to = required_param('to', PARAM_INT); $controller->move($id, $to); exit; case 'delete': $id = required_param('id', PARAM_INT); $controller->delete($id); exit; } throw new sharing_cart\exception('invalidoperation'); } catch (Exception $ex) { header('HTTP/1.1 400 Bad Request'); $json = array('message' => $ex->getMessage()); if (!empty($CFG->debug) and $CFG->debug >= DEBUG_DEVELOPER) { $json += array('file' => substr($ex->getFile(), strlen($CFG->dirroot)), 'line' => $ex->getLine(), 'trace' => format_backtrace($ex->getTrace(), true)); } echo json_encode($json); }
/** * Private method. Used by printPass/Fail/Skip/Error. */ function _paintPassFail($passorfail, $message, $stacktrace = null, $debuginfo = null) { global $CFG, $OUTPUT; echo $OUTPUT->box_start($passorfail . ' generalbox '); $url = $this->_htmlEntities($this->_stripParameterFromUrl(qualified_me(), 'path')); echo '<b class="', $passorfail, '">', $this->get_string($passorfail), '</b>: '; $breadcrumb = $this->getTestList(); array_shift($breadcrumb); $file = array_shift($breadcrumb); $pathbits = preg_split('/\\/|\\\\/', substr($file, strlen($CFG->dirroot) + 1)); $file = array_pop($pathbits); $folder = ''; foreach ($pathbits as $pathbit) { $folder .= $pathbit . '/'; echo "<a href=\"{$url}path={$folder}\" title=\"{$this->strrunonlyfolder}\">{$pathbit}</a>/"; } echo "<a href=\"{$url}path={$folder}{$file}\" title=\"{$this->strrunonlyfile}\">{$file}</a>"; echo $this->strseparator, implode($this->strseparator, $breadcrumb); echo '<br />', $this->_htmlEntities($message), "\n\n"; if (!empty($debuginfo)) { print_object('Debug info:'); print_object($debuginfo); } if ($stacktrace) { $dotsadded = false; $interestinglines = 0; $filteredstacktrace = array(); foreach ($stacktrace as $frame) { if (empty($frame['file']) || strpos($frame['file'], 'simpletestlib') === false && strpos($frame['file'], 'simpletestcoveragelib') === false && strpos($frame['file'], 'tool/unittest') === false) { $filteredstacktrace[] = $frame; $interestinglines += 1; $dotsadded = false; } else { if (!$dotsadded) { $filteredstacktrace[] = array('line' => '...', 'file' => '...'); $dotsadded = true; } } } if ($interestinglines > 1 || $passorfail == 'exception' && $interestinglines > 0) { echo '<div class="notifytiny">' . format_backtrace($filteredstacktrace) . "</div>\n\n"; } } echo $OUTPUT->box_end(); flush(); }
function cobalt_exception_handler($ex) { global $CFG, $DB, $OUTPUT, $USER, $FULLME, $SESSION, $PAGE; // detect active db transactions, rollback and log as error abort_all_db_transactions(); $info = get_cobaltexception_info($ex); if (($ex instanceof required_capability_exception) && !CLI_SCRIPT && !AJAX_SCRIPT && !empty($CFG->autologinguests) && !empty($USER->autologinguest)) { $SESSION->wantsurl = qualified_me(); redirect(get_login_url()); } 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->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); } cobaltexception_format($ex); } 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->link, $info->backtrace, $info->debuginfo, $info->errorcode); } else { echo bootstrap_renderer::early_error_content($info->message, $info->link, $info->backtrace, $info->debuginfo); $outinfo = get_exception_info($out_ex); echo bootstrap_renderer::early_error_content($outinfo->message, $outinfo->link, $outinfo->backtrace, $outinfo->debuginfo); } } } exit(1); // General error code }
/** * This function should only be called by this class, or from exception handlers * @static * @param string $message error message * @param string $moreinfourl (ignored in early errors) * @param string $link (ignored in early errors) * @param array $backtrace * @param string $debuginfo extra information for developers * @return string */ public static function early_error($message, $moreinfourl, $link, $backtrace, $debuginfo = null, $errorcode = null) { global $CFG; if (CLI_SCRIPT) { echo "!!! {$message} !!!\n"; if (!empty($CFG->debug) and $CFG->debug >= DEBUG_DEVELOPER) { if (!empty($debuginfo)) { echo "\nDebug info: {$debuginfo}"; } if (!empty($backtrace)) { echo "\nStack trace: " . format_backtrace($backtrace, true); } } return; } else { if (AJAX_SCRIPT) { $e = new stdClass(); $e->error = $message; $e->stacktrace = NULL; $e->debuginfo = NULL; if (!empty($CFG->debug) and $CFG->debug >= DEBUG_DEVELOPER) { if (!empty($debuginfo)) { $e->debuginfo = $debuginfo; } if (!empty($backtrace)) { $e->stacktrace = format_backtrace($backtrace, true); } } $e->errorcode = $errorcode; @header('Content-Type: application/json; charset=utf-8'); echo json_encode($e); return; } } // In the name of protocol correctness, monitoring and performance // profiling, set the appropriate error headers for machine consumption if (isset($_SERVER['SERVER_PROTOCOL'])) { // Avoid it with cron.php. Note that we assume it's HTTP/1.x // The 503 ode here means our Moodle does not work at all, the error happened too early @header($_SERVER['SERVER_PROTOCOL'] . ' 503 Service Unavailable'); } // better disable any caching @header('Content-Type: text/html; charset=utf-8'); @header('X-UA-Compatible: IE=edge'); @header('Cache-Control: no-store, no-cache, must-revalidate'); @header('Cache-Control: post-check=0, pre-check=0', false); @header('Pragma: no-cache'); @header('Expires: Mon, 20 Aug 1969 09:23:00 GMT'); @header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); if (function_exists('get_string')) { $strerror = get_string('error'); } else { $strerror = 'Error'; } $content = self::early_error_content($message, $moreinfourl, $link, $backtrace, $debuginfo); return self::plain_page($strerror, $content); }
/** * @private - do NOT call directly. */ public static function shutdown_handler() { global $DB; // Custom stuff first. foreach (self::$callbacks as $data) { list($callback, $params) = $data; try { if (!is_callable($callback)) { error_log('Invalid custom shutdown function detected ' . var_export($callback, true)); continue; } if ($params === null) { call_user_func($callback); } else { call_user_func_array($callback, $params); } } catch (Exception $e) { error_log('Exception ignored in shutdown function ' . var_export($callback, true) . ':' . $e->getMessage()); } } // Handle DB transactions, session need to be written afterwards // in order to maintain consistency in all session handlers. if ($DB->is_transaction_started()) { if (!defined('PHPUNIT_TEST') or !PHPUNIT_TEST) { // This should not happen, it usually indicates wrong catching of exceptions, // because all transactions should be finished manually or in default exception handler. $backtrace = $DB->get_transaction_start_backtrace(); error_log('Potential coding error - active database transaction detected during request shutdown:' . "\n" . format_backtrace($backtrace, true)); } $DB->force_transaction_rollback(); } // Close sessions - do it here to make it consistent for all session handlers. \core\session\manager::write_close(); // Other cleanup. self::request_shutdown(); // Stop profiling. if (function_exists('profiling_is_running')) { if (profiling_is_running()) { profiling_stop(); } } // NOTE: do not dispose $DB and MUC here, they might be used from legacy shutdown functions. }