X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=CRM%2FCore%2FError.php;h=cb4c217a3a1cbd3de5016f7e2ca5ee7456620d8d;hb=8d469992190aa62e0241bb124f8de3a65033f9aa;hp=652d55832af0e49ff03acb8ca6c00458fbaed634;hpb=8f1d62cd6d7c07fa73caea9d9160512bcb98e756;p=civicrm-core.git diff --git a/CRM/Core/Error.php b/CRM/Core/Error.php index 652d55832a..cb4c217a3a 100644 --- a/CRM/Core/Error.php +++ b/CRM/Core/Error.php @@ -1,8 +1,7 @@ ') { + public static function displaySessionError(&$error, $separator = '
') { $message = self::getMessages($error, $separator); if ($message) { $status = ts("Payment Processor Error message") . "{$separator} $message"; @@ -171,15 +163,14 @@ class CRM_Core_Error extends PEAR_ErrorStack { } /** - * create the main callback method. this method centralizes error processing. + * Create the main callback method. this method centralizes error processing. * * the errors we expect are from the pear modules DB, DB_DataObject * which currently use PEAR::raiseError to notify of error messages. * - * @param object PEAR_Error + * @param object $pearError PEAR_Error * * @return void - * @access public */ public static function handle($pearError) { @@ -192,16 +183,25 @@ class CRM_Core_Error extends PEAR_ErrorStack { } // create the error array - $error = array(); - $error['callback'] = $pearError->getCallback(); - $error['code'] = $pearError->getCode(); - $error['message'] = $pearError->getMessage(); - $error['mode'] = $pearError->getMode(); + $error = array(); + $error['callback'] = $pearError->getCallback(); + $error['code'] = $pearError->getCode(); + $error['message'] = $pearError->getMessage(); + $error['mode'] = $pearError->getMode(); $error['debug_info'] = $pearError->getDebugInfo(); - $error['type'] = $pearError->getType(); - $error['user_info'] = $pearError->getUserInfo(); - $error['to_string'] = $pearError->toString(); - if (function_exists('mysql_error') && + $error['type'] = $pearError->getType(); + $error['user_info'] = $pearError->getUserInfo(); + $error['to_string'] = $pearError->toString(); + + // We access connection info via _DB_DATAOBJECT instead + // of, e.g., calling getDatabaseConnection(), so that we + // can avoid infinite loops. + global $_DB_DATAOBJECT; + + if (!isset($_DB_DATAOBJECT['CONFIG']['database'])) { + // we haven't setup sql, so it's not our sql error... + } + elseif (preg_match('/^mysql:/', $_DB_DATAOBJECT['CONFIG']['database']) && mysql_error() ) { $mysql_error = mysql_error() . ', ' . mysql_errno(); @@ -210,13 +210,9 @@ class CRM_Core_Error extends PEAR_ErrorStack { // execute a dummy query to clear error stack mysql_query('select 1'); } - elseif (function_exists('mysqli_error')) { + elseif (preg_match('/^mysqli:/', $_DB_DATAOBJECT['CONFIG']['database'])) { $dao = new CRM_Core_DAO(); - // we do it this way, since calling the function - // getDatabaseConnection could potentially result - // in an infinite loop - global $_DB_DATAOBJECT; if (isset($_DB_DATAOBJECT['CONNECTIONS'][$dao->_database_dsn_md5])) { $conn = $_DB_DATAOBJECT['CONNECTIONS'][$dao->_database_dsn_md5]; $link = $conn->connection; @@ -254,24 +250,25 @@ class CRM_Core_Error extends PEAR_ErrorStack { self::abend(1); } - // this function is used to trap and print errors - // during system initialization time. Hence the error - // message is quite ugly /** + * this function is used to trap and print errors + * during system initialization time. Hence the error + * message is quite ugly + * * @param $pearError */ public static function simpleHandler($pearError) { // create the error array - $error = array(); - $error['callback'] = $pearError->getCallback(); - $error['code'] = $pearError->getCode(); - $error['message'] = $pearError->getMessage(); - $error['mode'] = $pearError->getMode(); + $error = array(); + $error['callback'] = $pearError->getCallback(); + $error['code'] = $pearError->getCode(); + $error['message'] = $pearError->getMessage(); + $error['mode'] = $pearError->getMode(); $error['debug_info'] = $pearError->getDebugInfo(); - $error['type'] = $pearError->getType(); - $error['user_info'] = $pearError->getUserInfo(); - $error['to_string'] = $pearError->toString(); + $error['type'] = $pearError->getType(); + $error['user_info'] = $pearError->getUserInfo(); + $error['to_string'] = $pearError->toString(); // ensure that debug does not check permissions since we are in bootstrap // mode and need to print a decent message to help the user @@ -294,29 +291,26 @@ class CRM_Core_Error extends PEAR_ErrorStack { * Also, if we do not return any value the PEAR_ErrorStack::push() then does the * action of PEAR_ERRORSTACK_PUSHANDLOG which displays the errors on the screen, * since the logger set for this error stack is 'display' - see CRM_Core_Config::getLog(); - * */ public static function handlePES($pearError) { return PEAR_ERRORSTACK_PUSH; } /** - * display an error page with an error message describing what happened + * Display an error page with an error message describing what happened. * - * @param null $message - * @param null $code - * @param null $email + * @param string $message + * The error message. + * @param string $code + * The error code if any. + * @param string $email + * The email address to notify of this situation. * * @throws Exception - * @internal param \message $string the error message - * @internal param \code $string the error code if any - * @internal param \email $string the email address to notify of this situation * * @return void - * @static - * @acess public */ - static function fatal($message = NULL, $code = NULL, $email = NULL) { + public static function fatal($message = NULL, $code = NULL, $email = NULL) { $vars = array( 'message' => $message, 'code' => $code, @@ -330,7 +324,7 @@ class CRM_Core_Error extends PEAR_ErrorStack { $details = 'A fatal error was triggered'; if ($message) { $details .= ': ' . $message; - } + } throw new Exception($details, $code); } @@ -361,6 +355,13 @@ class CRM_Core_Error extends PEAR_ErrorStack { } } + if ($config->backtrace) { + self::backtrace(); + } + + CRM_Core_Error::debug_var('Fatal Error Details', $vars); + CRM_Core_Error::backtrace('backTrace', TRUE); + // If we are in an ajax callback, format output appropriately if (CRM_Utils_Array::value('snippet', $_REQUEST) === CRM_Core_Smarty::PRINT_JSON) { $out = array( @@ -376,22 +377,16 @@ class CRM_Core_Error extends PEAR_ErrorStack { CRM_Core_Page_AJAX::returnJsonResponse($out); } - if ($config->backtrace) { - self::backtrace(); - } - $template = CRM_Core_Smarty::singleton(); $template->assign($vars); - CRM_Core_Error::debug_var('Fatal Error Details', $vars); - CRM_Core_Error::backtrace('backTrace', TRUE); $config->userSystem->outputError($template->fetch($config->fatalErrorTemplate)); self::abend(CRM_Core_Error::FATAL_ERROR); } /** - * display an error page with an error message describing what happened + * Display an error page with an error message describing what happened. * * This function is evil -- it largely replicates fatal(). Hopefully the * entire CRM_Core_Error system can be hollowed out and replaced with @@ -400,10 +395,15 @@ class CRM_Core_Error extends PEAR_ErrorStack { * @param Exception $exception * * @return void - * @static - * @acess public */ - static function handleUnhandledException($exception) { + public static function handleUnhandledException($exception) { + try { + CRM_Utils_Hook::unhandledException($exception); + } + catch (Exception $other) { + // if the exception-handler generates an exception, then that sucks! oh, well. carry on. + CRM_Core_Error::debug_var('handleUnhandledException_nestedException', self::formatTextException($other)); + } $config = CRM_Core_Config::singleton(); $vars = array( 'message' => $exception->getMessage(), @@ -464,22 +464,21 @@ class CRM_Core_Error extends PEAR_ErrorStack { } /** - * outputs pre-formatted debug information. Flushes the buffers + * Outputs pre-formatted debug information. Flushes the buffers * so we can interrupt a potential POST/redirect * - * @param string name of debug section - * @param mixed reference to variables that we need a trace of - * @param bool should we log or return the output - * @param bool whether to generate a HTML-escaped output - * @param bool should we check permissions before displaying output + * @param string $name name of debug section + * @param $variable mixed reference to variables that we need a trace of + * @param bool $log should we log or return the output + * @param bool $html whether to generate a HTML-escaped output + * @param bool $checkPermission should we check permissions before displaying output * useful when we die during initialization and permissioning * subsystem is not initialized - CRM-13765 * - * @return string the generated output - * @access public - * @static + * @return string + * the generated output */ - static function debug($name, $variable = NULL, $log = TRUE, $html = TRUE, $checkPermission = TRUE) { + public static function debug($name, $variable = NULL, $log = TRUE, $html = TRUE, $checkPermission = TRUE) { $error = self::singleton(); if ($variable === NULL) { @@ -516,30 +515,29 @@ class CRM_Core_Error extends PEAR_ErrorStack { * Similar to the function debug. Only difference is * in the formatting of the output. * - * @param $variable_name - * @param $variable + * @param string $variable_name + * @param mixed $variable * @param bool $print + * Should we use print_r ? (else we use var_dump). * @param bool $log - * @param string $comp variable name - * - * @internal param \reference $mixed to variables that we need a trace of - * @internal param \should $bool we use print_r ? (else we use var_dump) - * @internal param \should $bool we log or return the output + * Should we log or return the output. + * @param string $comp + * Variable name. * - * @return string the generated output + * @return string + * the generated output * - * @access public * - * @static * * @see CRM_Core_Error::debug() * @see CRM_Core_Error::debug_log_message() */ - static function debug_var($variable_name, + public static function debug_var( + $variable_name, $variable, $print = TRUE, - $log = TRUE, - $comp = '' + $log = TRUE, + $comp = '' ) { // check if variable is set if (!isset($variable)) { @@ -567,19 +565,20 @@ class CRM_Core_Error extends PEAR_ErrorStack { } /** - * display the error message on terminal + * Display the error message on terminal. * * @param $message - * @param bool $out should we log or return the output + * @param bool $out + * Should we log or return the output. * - * @param string $comp message to be output - * @return string format of the backtrace + * @param string $comp + * Message to be output. + * @return string + * format of the backtrace * - * @access public * - * @static */ - static function debug_log_message($message, $out = FALSE, $comp = '') { + public static function debug_log_message($message, $out = FALSE, $comp = '') { $config = CRM_Core_Config::singleton(); $file_log = self::createDebugLogger($comp); @@ -603,24 +602,39 @@ class CRM_Core_Error extends PEAR_ErrorStack { /** * Append to the query log (if enabled) */ - static function debug_query($string) { - if ( defined( 'CIVICRM_DEBUG_LOG_QUERY' ) ) { - if ( CIVICRM_DEBUG_LOG_QUERY == 'backtrace' ) { - CRM_Core_Error::backtrace( $string, true ); - } else if ( CIVICRM_DEBUG_LOG_QUERY ) { - CRM_Core_Error::debug_var( 'Query', $string, false, true ); + public static function debug_query($string) { + if (defined('CIVICRM_DEBUG_LOG_QUERY')) { + if (CIVICRM_DEBUG_LOG_QUERY == 'backtrace') { + CRM_Core_Error::backtrace($string, TRUE); } + elseif (CIVICRM_DEBUG_LOG_QUERY) { + CRM_Core_Error::debug_var('Query', $string, FALSE, TRUE); + } + } + } + + /** + * Execute a query and log the results. + * + * @param string $query + */ + public static function debug_query_result($query) { + $dao = CRM_Core_DAO::executeQuery($query); + $results = array(); + while ($dao->fetch()) { + $results[] = (array) $dao; } + CRM_Core_Error::debug_var('dao result', array('query' => $query, 'results' => $results)); } /** - * Obtain a reference to the error log + * Obtain a reference to the error log. * * @param string $comp * * @return Log */ - static function createDebugLogger($comp = '') { + public static function createDebugLogger($comp = '') { $config = CRM_Core_Config::singleton(); if ($comp) { @@ -652,7 +666,7 @@ class CRM_Core_Error extends PEAR_ErrorStack { * @param string $msg * @param bool $log */ - static function backtrace($msg = 'backTrace', $log = FALSE) { + public static function backtrace($msg = 'backTrace', $log = FALSE) { $backTrace = debug_backtrace(); $message = self::formatBacktrace($backTrace); if (!$log) { @@ -664,33 +678,40 @@ class CRM_Core_Error extends PEAR_ErrorStack { } /** - * Render a backtrace array as a string + * Render a backtrace array as a string. * - * @param array $backTrace array of stack frames - * @param boolean $showArgs TRUE if we should try to display content of function arguments (which could be sensitive); FALSE to display only the type of each function argument - * @param int $maxArgLen maximum number of characters to show from each argument string - * @return string printable plain-text + * @param array $backTrace + * Array of stack frames. + * @param bool $showArgs + * TRUE if we should try to display content of function arguments (which could be sensitive); FALSE to display only the type of each function argument. + * @param int $maxArgLen + * Maximum number of characters to show from each argument string. + * @return string + * printable plain-text */ - static function formatBacktrace($backTrace, $showArgs = TRUE, $maxArgLen = 80) { + public static function formatBacktrace($backTrace, $showArgs = TRUE, $maxArgLen = 80) { $message = ''; foreach (self::parseBacktrace($backTrace, $showArgs, $maxArgLen) as $idx => $trace) { $message .= sprintf("#%s %s\n", $idx, $trace); } - $message .= sprintf("#%s {main}\n", 1+$idx); + $message .= sprintf("#%s {main}\n", 1 + $idx); return $message; } /** - * Render a backtrace array as an array + * Render a backtrace array as an array. * - * @param array $backTrace array of stack frames - * @param boolean $showArgs TRUE if we should try to display content of function arguments (which could be sensitive); FALSE to display only the type of each function argument - * @param int $maxArgLen maximum number of characters to show from each argument string + * @param array $backTrace + * Array of stack frames. + * @param bool $showArgs + * TRUE if we should try to display content of function arguments (which could be sensitive); FALSE to display only the type of each function argument. + * @param int $maxArgLen + * Maximum number of characters to show from each argument string. * @return array * @see debug_backtrace * @see Exception::getTrace() */ - static function parseBacktrace($backTrace, $showArgs = TRUE, $maxArgLen = 80) { + public static function parseBacktrace($backTrace, $showArgs = TRUE, $maxArgLen = 80) { $ret = array(); foreach ($backTrace as $trace) { $args = array(); @@ -702,7 +723,7 @@ class CRM_Core_Error extends PEAR_ErrorStack { if (!empty($trace['args'])) { foreach ($trace['args'] as $arg) { - if (! $showArgs || $skipArgs) { + if (!$showArgs || $skipArgs) { $args[] = '(' . gettype($arg) . ')'; continue; } @@ -710,25 +731,32 @@ class CRM_Core_Error extends PEAR_ErrorStack { case 'boolean': $args[] = $arg ? 'TRUE' : 'FALSE'; break; + case 'integer': case 'double': $args[] = $arg; break; + case 'string': - $args[] = '"' . CRM_Utils_String::ellipsify(addcslashes((string) $arg, "\r\n\t\""), $maxArgLen). '"'; + $args[] = '"' . CRM_Utils_String::ellipsify(addcslashes((string) $arg, "\r\n\t\""), $maxArgLen) . '"'; break; + case 'array': - $args[] = '(Array:'.count($arg).')'; + $args[] = '(Array:' . count($arg) . ')'; break; + case 'object': $args[] = 'Object(' . get_class($arg) . ')'; break; + case 'resource': $args[] = 'Resource'; break; + case 'NULL': $args[] = 'NULL'; break; + default: $args[] = "($type)"; break; @@ -749,12 +777,13 @@ class CRM_Core_Error extends PEAR_ErrorStack { } /** - * Render an exception as HTML string + * Render an exception as HTML string. * * @param Exception $e - * @return string printable HTML text + * @return string + * printable HTML text */ - static function formatHtmlException(Exception $e) { + public static function formatHtmlException(Exception $e) { $msg = ''; // Exception metadata @@ -769,13 +798,14 @@ class CRM_Core_Error extends PEAR_ErrorStack { $msg .= ''; foreach (array('Type', 'Code', 'Message', 'Mode', 'UserInfo', 'DebugInfo') as $f) { $msg .= sprintf('%s%s', $f, call_user_func(array($ei->getCause(), "get$f"))); - } + } $msg .= ''; - } + } $ei = $ei->getCause(); - } + } $msg .= $e->toHtml(); - } else { + } + else { $msg .= '

' . get_class($e) . ': "' . htmlentities($e->getMessage()) . '"

'; $msg .= '
' . htmlentities(self::formatBacktrace($e->getTrace())) . '
'; } @@ -783,12 +813,13 @@ class CRM_Core_Error extends PEAR_ErrorStack { } /** - * Write details of an exception to the log + * Write details of an exception to the log. * * @param Exception $e - * @return string printable plain text + * @return string + * printable plain text */ - static function formatTextException(Exception $e) { + public static function formatTextException(Exception $e) { $msg = get_class($e) . ": \"" . $e->getMessage() . "\"\n"; $ei = $e; @@ -808,11 +839,11 @@ class CRM_Core_Error extends PEAR_ErrorStack { * @param $message * @param int $code * @param string $level - * @param null $params + * @param array $params * * @return object */ - static function createError($message, $code = 8000, $level = 'Fatal', $params = NULL) { + public static function createError($message, $code = 8000, $level = 'Fatal', $params = NULL) { $error = CRM_Core_Error::singleton(); $error->push($code, $level, array($params), $message); return $error; @@ -821,13 +852,12 @@ class CRM_Core_Error extends PEAR_ErrorStack { /** * Set a status message in the session, then bounce back to the referrer. * - * @param string $status The status message to set + * @param string $status + * The status message to set. * * @param null $redirect * @param string $title * @return void - * @access public - * @static */ public static function statusBounce($status, $redirect = NULL, $title = NULL) { $session = CRM_Core_Session::singleton(); @@ -845,10 +875,8 @@ class CRM_Core_Error extends PEAR_ErrorStack { } /** - * Function to reset the error stack + * Reset the error stack. * - * @access public - * @static */ public static function reset() { $error = self::singleton(); @@ -870,10 +898,10 @@ class CRM_Core_Error extends PEAR_ErrorStack { /** * PEAR error-handler to quietly catch otherwise fatal errors. Intended for use with smtp transport. * - * @param object $obj The PEAR_ERROR object - * @return object $obj - * @access public - * @static + * @param object $obj + * The PEAR_ERROR object. + * @return object + * $obj */ public static function nullHandler($obj) { CRM_Core_Error::debug_log_message("Ignoring exception thrown by nullHandler: {$obj->code}, {$obj->message}"); @@ -881,12 +909,11 @@ class CRM_Core_Error extends PEAR_ErrorStack { return $obj; } - /* + /** * @deprecated * This function is no longer used by v3 api. * @fixme Some core files call it but it should be re-thought & renamed or removed - */ - /** + * * @param $msg * @param null $data * @@ -922,7 +949,7 @@ class CRM_Core_Error extends PEAR_ErrorStack { } /** - * Terminate execution abnormally + * Terminate execution abnormally. */ protected static function abend($code) { // do a hard rollback of any pending transactions @@ -932,8 +959,8 @@ class CRM_Core_Error extends PEAR_ErrorStack { } /** - * @param $error - * @param const $type + * @param array $error + * @param int $type * * @return bool */ @@ -946,6 +973,7 @@ class CRM_Core_Error extends PEAR_ErrorStack { } return FALSE; } + } $e = new PEAR_ErrorStack('CRM');