diff --git a/core/Error.php b/core/Error.php index 3ec648e8f2820fcc47d03f80c786c711a0a2f1b3..d31ff36de8b4a7a3af61340446bbb502e39389a0 100644 --- a/core/Error.php +++ b/core/Error.php @@ -139,11 +139,11 @@ class Error public static function setErrorHandler() { - Piwik_AddAction('Log.formatFileMessage', array('Error', 'formatFileAndDBLogMessage')); - Piwik_AddAction('Log.formatDatabaseMessage', array('Error', 'formatFileAndDBLogMessage')); - Piwik_AddAction('Log.formatScreenMessage', array('Error', 'formatScreenMessage')); + Piwik_AddAction('Log.formatFileMessage', array('\\Piwik\\Error', 'formatFileAndDBLogMessage')); + Piwik_AddAction('Log.formatDatabaseMessage', array('\\Piwik\\Error', 'formatFileAndDBLogMessage')); + Piwik_AddAction('Log.formatScreenMessage', array('\\Piwik\\Error', 'formatScreenMessage')); - set_error_handler(array('Error', 'errorHandler')); + set_error_handler(array('\\Piwik\\Error', 'errorHandler')); } public static function errorHandler($errno, $errstr, $errfile, $errline) @@ -153,7 +153,7 @@ class Error return; } - $plugin = false; + $plugin = 'unknown'; $backtrace = ''; $bt = @debug_backtrace(); @@ -166,18 +166,13 @@ class Error . '(...) called at [' . (isset($debug['file']) ? $debug['file'] : '') . ':' . (isset($debug['line']) ? $debug['line'] : '') . ']' . "\n"; - - // try and discern the plugin name - if (empty($plugin)) { - if (preg_match("/^Piwik\\Plugins\\([a-z_]+)\\/", $debug['class'], $matches)) { - $plugin = $matches[1]; - } - } } + + $plugin = Plugin::getPluginNameFromBacktrace($bt); } $error = new Error($errno, $errstr, $errfile, $errline, $backtrace); - Log::e($plugin ?: 'unknown', $error); + Log::e($plugin, $error); switch ($errno) { case E_ERROR: diff --git a/core/ExceptionHandler.php b/core/ExceptionHandler.php index ac632f166014e86b4bc8fc27a53b7288ce9421d1..62b0bd2a77cb54a088a6eb40ed2f85bd9c71a4e6 100644 --- a/core/ExceptionHandler.php +++ b/core/ExceptionHandler.php @@ -8,39 +8,60 @@ * @category Piwik * @package Piwik */ +namespace Piwik; + +use Piwik\Common; use Piwik\Piwik; +use Piwik\Plugin; use Piwik\Log; use Piwik\FrontController; +use Piwik\API\ResponseBuilder; /** - * Exception handler used to display nicely exceptions in Piwik - * - * @param Exception $exception - * @throws Exception + * TODO */ -function Piwik_ExceptionHandler(Exception $exception) +class ExceptionHandler { - try { - Log::e("%s (%s): %s", array($exception->getFile(), $exception->getLine(), $exception->getMessage())); // TODO add backtrace? - } catch (Exception $e) { - if (FrontController::shouldRethrowException()) { - throw $exception; + public static function setUp() + { + Piwik_AddAction('Log.formatFileMessage', array('\\Piwik\\ExceptionHandler', 'formatFileAndDBLogMessage')); + Piwik_AddAction('Log.formatDatabaseMessage', array('\\Piwik\\ExceptionHandler', 'formatFileAndDBLogMessage')); + Piwik_AddAction('Log.formatScreenMessage', array('\\Piwik\\ExceptionHandler', 'formatScreenMessage')); + + set_exception_handler(array('\\Piwik\\ExceptionHandler', 'exceptionHandler')); + } + + public static function formatFileAndDBLogMessage(&$message, $level, $pluginName, $datetime, $log) + { + if ($message instanceof \Exception) { + $message = sprintf("%s(%d): %s\n%s", $message->getFile(), $message->getLine(), $message->getMessage(), + $message->getTraceAsString()); + + $message = $log->formatMessage($level, $pluginName, $datetime, $message); } + } - // case when the exception is raised before the logger being ready - // we handle the exception a la mano, but using the Logger formatting properties - $event = array(); - $event['errno'] = $exception->getCode(); - $event['message'] = $exception->getMessage(); - $event['errfile'] = $exception->getFile(); - $event['errline'] = $exception->getLine(); - $event['backtrace'] = $exception->getTraceAsString(); + public static function formatScreenMessage(&$message, $level, $pluginName, $datetime, $log) + { + if ($message instanceof \Exception) { + if (!Common::isPhpCliMode()) { + @header('Content-Type: text/html; charset=utf-8'); + } - $formatter = new ExceptionScreenFormatter(); + $outputFormat = strtolower(Common::getRequestVar('format', 'html', 'string')); + $response = new ResponseBuilder($outputFormat); + $message = $response->getResponseException(new \Exception($message->getMessage())); + } + } - $message = $formatter->format($event); - $message .= "<br /><br />And this exception raised another exception \"" . $e->getMessage() . "\""; + public static function exceptionHandler(Exception $exception) + { + $plugin = Plugin::getPluginNameFromBacktrace($exception->getTrace()); + Log::e($plugin, $exception); - Piwik::exitWithErrorMessage($message); + // TODO: what about this code? + /*if (FrontController::shouldRethrowException()) { + throw $exception; + }*/ } -} +} \ No newline at end of file diff --git a/core/Log.php b/core/Log.php index 9e64512012e9d26db321ae477738198286094c32..e98ac5e6fe13d090fcf3d8e38cf23954f3fc3c03 100644 --- a/core/Log.php +++ b/core/Log.php @@ -155,8 +155,6 @@ class Log private function createWriterByName($writerName) { - $self = $this; - $writer = false; if ($writerName == 'file') { $writer = array($this, 'logToFile'); diff --git a/core/Plugin.php b/core/Plugin.php index 5f0c809896d6cd92df373b267b679b4025320c63..c8f48590a4879d187a96db69907c26a6ed3c47be 100644 --- a/core/Plugin.php +++ b/core/Plugin.php @@ -193,4 +193,18 @@ class Plugin { return $this->pluginName; } -} + + public static function getPluginNameFromBacktrace($backtrace) + { + $plugin = false; + foreach ($backtrace as $tracepoint) { + // try and discern the plugin name + if (empty($plugin)) { + if (preg_match("/^Piwik\\Plugins\\([a-z_]+)\\/", $tracepoint['class'], $matches)) { + $plugin = $matches[1]; + } + } + } + return $plugin ?: 'unknown'; + } +} \ No newline at end of file diff --git a/index.php b/index.php index 0839100d325abba5c1a71da46e4a429bc5c002b8..0ffa6ea99c02da6e16f8215354d5b7782ddc71b2 100644 --- a/index.php +++ b/index.php @@ -10,6 +10,7 @@ use Piwik\FrontController; use Piwik\Error; +use Piwik\ExceptionHandler; define('PIWIK_DOCUMENT_ROOT', dirname(__FILE__) == '/' ? '' : dirname(__FILE__)); if (file_exists(PIWIK_DOCUMENT_ROOT . '/bootstrap.php')) { @@ -44,7 +45,7 @@ if (!defined('PIWIK_ENABLE_ERROR_HANDLER') || PIWIK_ENABLE_ERROR_HANDLER) { Error::setErrorHandler(); require_once PIWIK_INCLUDE_PATH . '/core/ExceptionHandler.php'; - set_exception_handler('Piwik_ExceptionHandler'); + ExceptionHandler::setUp(); } if (!defined('PIWIK_ENABLE_DISPATCH') || PIWIK_ENABLE_DISPATCH) {