public function __construct($message, \ErrorException $previous) { parent::__construct($message, $previous->getCode(), $previous->getSeverity(), $previous->getFile(), $previous->getLine(), $previous->getPrevious()); $this->setTrace($previous->getTrace()); }
/** * Log error exceptions to user console using JSON_Response::error * * @param ErrorException $err_exc The error exception * @return void * @uses JSON_Response */ public function consoleErrorException(\ErrorException $err_exc) { Core\JSON_Response::load()->error(['message' => $err_exc->getMessage(), 'code' => $err_exc->getCode(), 'severity' => $err_exc->getSeverity(), 'line' => $err_exc->getLine(), 'file' => $err_exc->getFile(), 'trace' => $err_exc->getTrace()]); }
/** * Handles errors by filtering then logging them according to the configured bit fields. * * @param int $type One of the E_* constants * @param string $file * @param int $line * @param array $context * * @return bool Returns false when no handling happens so that the PHP engine can handle the error itself. * * @throws \ErrorException When $this->thrownErrors requests so * * @internal */ public function handleError($type, $message, $file, $line, array $context, array $backtrace = null) { $level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED; $log = $this->loggedErrors & $type; $throw = $this->thrownErrors & $type & $level; $type &= $level | $this->screamedErrors; if (!$type || !$log && !$throw) { return $type && $log; } if (null !== $backtrace && $type & E_ERROR) { // E_ERROR fatal errors are triggered on HHVM when // hhvm.error_handling.call_user_handler_on_fatals=1 // which is the way to get their backtrace. $this->handleFatalError(compact('type', 'message', 'file', 'line', 'backtrace')); return true; } if ($throw) { if (null !== self::$toStringException) { $throw = self::$toStringException; self::$toStringException = null; } elseif ($this->scopedErrors & $type && class_exists(ContextErrorException::class)) { $throw = new ContextErrorException($this->levels[$type] . ': ' . $message, 0, $type, $file, $line, $context); } else { $throw = new \ErrorException($this->levels[$type] . ': ' . $message, 0, $type, $file, $line); } if (E_USER_ERROR & $type) { $backtrace = $backtrace ?: $throw->getTrace(); for ($i = 1; isset($backtrace[$i]); ++$i) { if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function']) && '__toString' === $backtrace[$i]['function'] && '->' === $backtrace[$i]['type'] && !isset($backtrace[$i - 1]['class']) && ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])) { // Here, we know trigger_error() has been called from __toString(). // HHVM is fine with throwing from __toString() but PHP triggers a fatal error instead. // A small convention allows working around the limitation: // given a caught $e exception in __toString(), quitting the method with // `return trigger_error($e, E_USER_ERROR);` allows this error handler // to make $e get through the __toString() barrier. foreach ($context as $e) { if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) { if (1 === $i) { // On HHVM $throw = $e; break; } self::$toStringException = $e; return true; } } if (1 < $i) { // On PHP (not on HHVM), display the original error message instead of the default one. $this->handleException($throw); // Stop the process by giving back the error to the native handler. return false; } } } } throw $throw; } // For duplicated errors, log the trace only once $e = md5("{$type}/{$line}/{$file}{$message}", true); $trace = true; if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) { $trace = false; } else { $this->loggedTraces[$e] = 1; } $e = compact('type', 'file', 'line', 'level'); if ($type & $level) { if ($this->scopedErrors & $type) { $e['scope_vars'] = $context; if ($trace) { $e['stack'] = $backtrace ?: debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT); } } elseif ($trace) { if (null === $backtrace) { $e['stack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); } else { foreach ($backtrace as &$frame) { unset($frame['args'], $frame); } $e['stack'] = $backtrace; } } } if ($this->isRecursive) { $log = 0; } elseif (self::$stackedErrorLevels) { self::$stackedErrors[] = array($this->loggers[$type][0], $type & $level ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e); } else { try { $this->isRecursive = true; $this->loggers[$type][0]->log($type & $level ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e); $this->isRecursive = false; } catch (\Exception $e) { $this->isRecursive = false; throw $e; } } return $type && $log; }
public function handleError($type, $message, $file, $line, array $context, array $backtrace = null) { $level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED; $log = $this->loggedErrors & $type; $throw = $this->thrownErrors & $type & $level; $type &= $level | $this->screamedErrors; if (!$type || !$log && !$throw) { return $type && $log; } if (isset($context['GLOBALS']) && $this->scopedErrors & $type) { unset($context['GLOBALS']); } if (null !== $backtrace && $type & E_ERROR) { $this->handleFatalError(compact('type', 'message', 'file', 'line', 'backtrace')); return true; } $logMessage = $this->levels[$type] . ': ' . $message; if (null !== self::$toStringException) { $errorAsException = self::$toStringException; self::$toStringException = null; } elseif (!$throw && !($type & $level)) { $errorAsException = new SilencedErrorContext($type, $file, $line); } else { if ($this->scopedErrors & $type) { $errorAsException = new ContextErrorException($logMessage, 0, $type, $file, $line, $context); } else { $errorAsException = new \ErrorException($logMessage, 0, $type, $file, $line); } if ($throw || $this->tracedErrors & $type) { $backtrace = $backtrace ?: $errorAsException->getTrace(); $lightTrace = $backtrace; for ($i = 0; isset($backtrace[$i]); ++$i) { if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) { $lightTrace = array_slice($lightTrace, 1 + $i); break; } } if (!($throw || $this->scopedErrors & $type)) { for ($i = 0; isset($lightTrace[$i]); ++$i) { unset($lightTrace[$i]['args']); } } $this->traceReflector->setValue($errorAsException, $lightTrace); } else { $this->traceReflector->setValue($errorAsException, array()); } } if ($throw) { if (E_USER_ERROR & $type) { for ($i = 1; isset($backtrace[$i]); ++$i) { if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function']) && '__toString' === $backtrace[$i]['function'] && '->' === $backtrace[$i]['type'] && !isset($backtrace[$i - 1]['class']) && ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])) { foreach ($context as $e) { if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) { if (1 === $i) { $errorAsException = $e; break; } self::$toStringException = $e; return true; } } if (1 < $i) { $this->handleException($errorAsException); return false; } } } } throw $errorAsException; } if ($this->isRecursive) { $log = 0; } elseif (self::$stackedErrorLevels) { self::$stackedErrors[] = array($this->loggers[$type][0], $type & $level ? $this->loggers[$type][1] : LogLevel::DEBUG, $logMessage, array('exception' => $errorAsException)); } else { try { $this->isRecursive = true; $level = $type & $level ? $this->loggers[$type][1] : LogLevel::DEBUG; $this->loggers[$type][0]->log($level, $logMessage, array('exception' => $errorAsException)); } finally { $this->isRecursive = false; } } return $type && $log; }
public function handleError($type, $message, $file, $line, array $context, array $backtrace = null) { $level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED; $log = $this->loggedErrors & $type; $throw = $this->thrownErrors & $type & $level; $type &= $level | $this->screamedErrors; if (!$type || !$log && !$throw) { return $type && $log; } if (null !== $backtrace && $type & E_ERROR) { $this->handleFatalError(compact('type', 'message', 'file', 'line', 'backtrace')); return true; } if ($throw) { if (null !== self::$toStringException) { $throw = self::$toStringException; self::$toStringException = null; } elseif ($this->scopedErrors & $type && class_exists(ContextErrorException::class)) { $throw = new ContextErrorException($this->levels[$type] . ': ' . $message, 0, $type, $file, $line, $context); } else { $throw = new \ErrorException($this->levels[$type] . ': ' . $message, 0, $type, $file, $line); } if (E_USER_ERROR & $type) { $backtrace = $backtrace ?: $throw->getTrace(); for ($i = 1; isset($backtrace[$i]); ++$i) { if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function']) && '__toString' === $backtrace[$i]['function'] && '->' === $backtrace[$i]['type'] && !isset($backtrace[$i - 1]['class']) && ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])) { foreach ($context as $e) { if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) { if (1 === $i) { $throw = $e; break; } self::$toStringException = $e; return true; } } if (1 < $i) { $this->handleException($throw); return false; } } } } throw $throw; } $e = md5("{$type}/{$line}/{$file}{$message}", true); $trace = true; if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) { $trace = false; } else { $this->loggedTraces[$e] = 1; } $e = compact('type', 'file', 'line', 'level'); if ($type & $level) { if ($this->scopedErrors & $type) { $e['scope_vars'] = $context; if ($trace) { $e['stack'] = $backtrace ?: debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT); } } elseif ($trace) { if (null === $backtrace) { $e['stack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); } else { foreach ($backtrace as &$frame) { unset($frame['args'], $frame); } $e['stack'] = $backtrace; } } } if ($this->isRecursive) { $log = 0; } elseif (self::$stackedErrorLevels) { self::$stackedErrors[] = array($this->loggers[$type][0], $type & $level ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e); } else { try { $this->isRecursive = true; $this->loggers[$type][0]->log($type & $level ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e); } finally { $this->isRecursive = false; } } return $type && $log; }
/** * Generic hook logging facility. * * @param string $hookName The hook name. * * @param array $params The parameters. * * @param bool $starting Flag determining if we are entering the hook or exiting. * * @return void */ protected function processHook($hookName, $params, $starting) { if (!$starting) { if (self::$timeCollector->hasStartedMeasure($hookName)) { self::$timeCollector->stopMeasure($hookName); } return; } if (self::$timeCollector && $hookName !== 'initializeSystem') { if (!self::$timeCollector->hasStartedMeasure($hookName)) { self::$timeCollector->startMeasure($hookName, $hookName); } } $exception = new \ErrorException(); $stack = $exception->getTrace(); $information = array('caller' => str_replace(TL_ROOT, 'TL_ROOT', $stack[1]['file']) . '#' . $stack[1]['line'], '$GLOBALS[\'TL_HOOKS\'][\'' . $hookName . '\']' => $this->createHookList($GLOBALS['TL_HOOKS'][$hookName]), 'parameters' => $this->prepareParams($hookName, $params)); $this->log($information, $hookName); }
/** * Handles errors by filtering then logging them according to the configured bit fields. * * @param int $type One of the E_* constants * @param string $message * @param string $file * @param int $line * @param array $context * @param array $backtrace * * @return bool Returns false when no handling happens so that the PHP engine can handle the error itself * * @throws \ErrorException When $this->thrownErrors requests so * * @internal */ public function handleError($type, $message, $file, $line, array $context, array $backtrace = null) { // Level is the current error reporting level to manage silent error. // Strong errors are not authorized to be silenced. $level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR | E_DEPRECATED | E_USER_DEPRECATED; $log = $this->loggedErrors & $type; $throw = $this->thrownErrors & $type & $level; $type &= $level | $this->screamedErrors; if (!$type || !$log && !$throw) { return $type && $log; } if (null !== $backtrace && $type & E_ERROR) { // E_ERROR fatal errors are triggered on HHVM when // hhvm.error_handling.call_user_handler_on_fatals=1 // which is the way to get their backtrace. $this->handleFatalError(compact('type', 'message', 'file', 'line', 'backtrace')); return true; } $logMessage = $this->levels[$type] . ': ' . $message; if (null !== self::$toStringException) { $errorAsException = self::$toStringException; self::$toStringException = null; } elseif (!$throw && !($type & $level)) { $errorAsException = new SilencedErrorContext($type, $file, $line); } else { if ($this->scopedErrors & $type) { $errorAsException = new ContextErrorException($logMessage, 0, $type, $file, $line, $context); } else { $errorAsException = new \ErrorException($logMessage, 0, $type, $file, $line); } // Clean the trace by removing function arguments and the first frames added by the error handler itself. if ($throw || $this->tracedErrors & $type) { $backtrace = $backtrace ?: $errorAsException->getTrace(); $lightTrace = $backtrace; for ($i = 0; isset($backtrace[$i]); ++$i) { if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) { $lightTrace = array_slice($lightTrace, 1 + $i); break; } } if (!($throw || $this->scopedErrors & $type)) { for ($i = 0; isset($lightTrace[$i]); ++$i) { unset($lightTrace[$i]['args']); } } $this->traceReflector->setValue($errorAsException, $lightTrace); } else { $this->traceReflector->setValue($errorAsException, array()); } } if ($throw) { if (E_USER_ERROR & $type) { for ($i = 1; isset($backtrace[$i]); ++$i) { if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function']) && '__toString' === $backtrace[$i]['function'] && '->' === $backtrace[$i]['type'] && !isset($backtrace[$i - 1]['class']) && ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])) { // Here, we know trigger_error() has been called from __toString(). // HHVM is fine with throwing from __toString() but PHP triggers a fatal error instead. // A small convention allows working around the limitation: // given a caught $e exception in __toString(), quitting the method with // `return trigger_error($e, E_USER_ERROR);` allows this error handler // to make $e get through the __toString() barrier. foreach ($context as $e) { if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) { if (1 === $i) { // On HHVM $errorAsException = $e; break; } self::$toStringException = $e; return true; } } if (1 < $i) { // On PHP (not on HHVM), display the original error message instead of the default one. $this->handleException($errorAsException); // Stop the process by giving back the error to the native handler. return false; } } } } throw $errorAsException; } if ($this->isRecursive) { $log = 0; } elseif (self::$stackedErrorLevels) { self::$stackedErrors[] = array($this->loggers[$type][0], $type & $level ? $this->loggers[$type][1] : LogLevel::DEBUG, $logMessage, array('exception' => $errorAsException)); } else { try { $this->isRecursive = true; $level = $type & $level ? $this->loggers[$type][1] : LogLevel::DEBUG; $this->loggers[$type][0]->log($level, $logMessage, array('exception' => $errorAsException)); } finally { $this->isRecursive = false; } } return $type && $log; }
/** * @param \ErrorException $e * @return array */ public static function createFromPHPError(\ErrorException $e) { return ['message' => $e->getMessage(), 'severity' => $e->getSeverity(), 'trace' => self::toSafeTrace($e->getTrace())]; }
function error_report(ErrorException $e) { echo 'Message:' . $e->getMessage() . "<br />"; $trace = $e->getTrace(); }
/** * Handles errors by filtering then logging them according to the configured bit fields. * * @param int $type One of the E_* constants * @param string $file * @param int $line * @param array $context * * @return bool Returns false when no handling happens so that the PHP engine can handle the error itself. * * @throws \ErrorException When $this->thrownErrors requests so * * @internal */ public function handleError($type, $message, $file, $line, array $context, array $backtrace = null) { $level = error_reporting() | E_RECOVERABLE_ERROR | E_USER_ERROR; $log = $this->loggedErrors & $type; $throw = $this->thrownErrors & $type & $level; $type &= $level | $this->screamedErrors; if (!$type || !$log && !$throw) { return $type && $log; } if (PHP_VERSION_ID < 50400 && isset($context['GLOBALS']) && $this->scopedErrors & $type) { $e = $context; // Whatever the signature of the method, unset($e['GLOBALS'], $context); // $context is always a reference in 5.3 $context = $e; } if (null !== $backtrace && $type & E_ERROR) { // E_ERROR fatal errors are triggered on HHVM when // hhvm.error_handling.call_user_handler_on_fatals=1 // which is the way to get their backtrace. $this->handleFatalError(compact('type', 'message', 'file', 'line', 'backtrace')); return true; } if ($throw) { if (null !== self::$toStringException) { $throw = self::$toStringException; self::$toStringException = null; } elseif ($this->scopedErrors & $type && class_exists('Symfony\\Component\\Debug\\Exception\\ContextErrorException')) { // Checking for class existence is a work around for https://bugs.php.net/42098 $throw = new ContextErrorException($this->levels[$type] . ': ' . $message, 0, $type, $file, $line, $context); } else { $throw = new \ErrorException($this->levels[$type] . ': ' . $message, 0, $type, $file, $line); } if (PHP_VERSION_ID <= 50407 && (PHP_VERSION_ID >= 50400 || PHP_VERSION_ID <= 50317)) { // Exceptions thrown from error handlers are sometimes not caught by the exception // handler and shutdown handlers are bypassed before 5.4.8/5.3.18. // We temporarily re-enable display_errors to prevent any blank page related to this bug. $throw->errorHandlerCanary = new ErrorHandlerCanary(); } if (E_USER_ERROR & $type) { $backtrace = $backtrace ?: $throw->getTrace(); for ($i = 1; isset($backtrace[$i]); ++$i) { if (isset($backtrace[$i]['function'], $backtrace[$i]['type'], $backtrace[$i - 1]['function']) && '__toString' === $backtrace[$i]['function'] && '->' === $backtrace[$i]['type'] && !isset($backtrace[$i - 1]['class']) && ('trigger_error' === $backtrace[$i - 1]['function'] || 'user_error' === $backtrace[$i - 1]['function'])) { // Here, we know trigger_error() has been called from __toString(). // HHVM is fine with throwing from __toString() but PHP triggers a fatal error instead. // A small convention allows working around the limitation: // given a caught $e exception in __toString(), quitting the method with // `return trigger_error($e, E_USER_ERROR);` allows this error handler // to make $e get through the __toString() barrier. foreach ($context as $e) { if (($e instanceof \Exception || $e instanceof \Throwable) && $e->__toString() === $message) { if (1 === $i) { // On HHVM $throw = $e; break; } self::$toStringException = $e; return true; } } if (1 < $i) { // On PHP (not on HHVM), display the original error message instead of the default one. $this->handleException($throw); // Stop the process by giving back the error to the native handler. return false; } } } } throw $throw; } // For duplicated errors, log the trace only once $e = md5("{$type}/{$line}/{$file}{$message}", true); $trace = true; if (!($this->tracedErrors & $type) || isset($this->loggedTraces[$e])) { $trace = false; } else { $this->loggedTraces[$e] = 1; } $e = compact('type', 'file', 'line', 'level'); if ($type & $level) { if ($this->scopedErrors & $type) { $e['scope_vars'] = $context; if ($trace) { $e['stack'] = $backtrace ?: debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT); } } elseif ($trace) { if (null === $backtrace) { $e['stack'] = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS); } else { foreach ($backtrace as &$frame) { unset($frame['args'], $frame); } $e['stack'] = $backtrace; } } } if ($this->isRecursive) { $log = 0; } elseif (self::$stackedErrorLevels) { self::$stackedErrors[] = array($this->loggers[$type][0], $type & $level ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e); } else { try { $this->isRecursive = true; $this->loggers[$type][0]->log($type & $level ? $this->loggers[$type][1] : LogLevel::DEBUG, $message, $e); $this->isRecursive = false; } catch (\Exception $e) { $this->isRecursive = false; throw $e; } } return $type && $log; }