diff --git a/mdeploy.php b/mdeploy.php index 27f50262fa0c1..8e5bfec9da24f 100644 --- a/mdeploy.php +++ b/mdeploy.php @@ -611,6 +611,49 @@ class output_http_provider extends output_provider { public function help() { // No help available via HTTP } + + /** + * Display the information about uncaught exception + * + * @param Exception $e uncaught exception + */ + public function exception(Exception $e) { + $this->start_output(); + echo('

Oops! It did it again

'); + echo('

Moodle deployment utility had a trouble with your request. See the debugging information for more details.

'); + echo('
');
+        echo exception_handlers::format_exception_info($e);
+        echo('
'); + $this->end_output(); + } + + // End of external API + + /** + * Produce the HTML page header + */ + protected function start_output() { + echo ' + + + + + + +
'; + } + + /** + * Produce the HTML page footer + */ + protected function end_output() { + echo '
'; + } } // The main class providing all the functionality ////////////////////////////// @@ -725,6 +768,15 @@ public function execute() { $this->done(self::EXIT_UNKNOWN_ACTION); } + /** + * Attempts to log a thrown exception + * + * @param Exception $e uncaught exception + */ + public function log_exception(Exception $e) { + $this->log($e->__toString()); + } + /** * Initialize the worker class. */ @@ -817,9 +869,9 @@ protected function log_location() { return $this->logfile; } - $dataroot = $this->input->get_option('dataroot', false); + $dataroot = $this->input->get_option('dataroot', ''); - if ($dataroot === false) { + if (empty($dataroot)) { $this->logfile = false; return $this->logfile; } @@ -1170,6 +1222,77 @@ protected function redirect($url) { } +/** + * Provides exception handlers for this script + */ +class exception_handlers { + + /** + * Sets the exception handler + * + * + * @param string $handler name + */ + public static function set_handler($handler) { + + if (PHP_SAPI === 'cli') { + // No custom handler available for CLI mode. + set_exception_handler(null); + return; + } + + set_exception_handler('exception_handlers::'.$handler.'_exception_handler'); + } + + /** + * Returns the text describing the thrown exception + * + * By default, PHP displays full path to scripts when the exception is thrown. In order to prevent + * sensitive information leak (and yes, the path to scripts at a web server _is_ sensitive information) + * the path to scripts is removed from the message. + * + * @param Exception $e thrown exception + * @return string + */ + public static function format_exception_info(Exception $e) { + + $mydir = dirname(__FILE__).'/'; + $text = $e->__toString(); + $text = str_replace($mydir, '', $text); + return $text; + } + + /** + * Very basic exception handler + * + * @param Exception $e uncaught exception + */ + public static function bootstrap_exception_handler(Exception $e) { + echo('

Oops! It did it again

'); + echo('

Moodle deployment utility had a trouble with your request. See the debugging information for more details.

'); + echo('
');
+        echo self::format_exception_info($e);
+        echo('
'); + } + + /** + * Default exception handler + * + * When this handler is used, input_manager and output_manager singleton instances already + * exist in the memory and can be used. + * + * @param Exception $e uncaught exception + */ + public static function default_exception_handler(Exception $e) { + + $worker = worker::instance(); + $worker->log_exception($e); + + $output = output_manager::instance(); + $output->exception($e); + } +} + //////////////////////////////////////////////////////////////////////////////// // Check if the script is actually executed or if it was just included by someone @@ -1177,8 +1300,10 @@ protected function redirect($url) { // if __name__ == '__main__' if (!debug_backtrace()) { // We are executed by the SAPI. + exception_handlers::set_handler('bootstrap'); // Initialize the worker class to actually make the job. $worker = worker::instance(); + exception_handlers::set_handler('default'); // Lights, Camera, Action! $worker->execute();