Same filename and directory in other branches
- 8.9.x core/lib/Drupal/Core/Utility/Error.php
- 9 core/lib/Drupal/Core/Utility/Error.php
Namespace
Drupal\Core\Utility
File
core/lib/Drupal/Core/Utility/Error.php
View source
<?php
namespace Drupal\Core\Utility;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\Xss;
use Drupal\Core\Database\Connection;
use Drupal\Core\Database\Database;
use Drupal\Core\Database\DatabaseExceptionWrapper;
use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
class Error {
const ERROR = 3;
const DEFAULT_ERROR_MESSAGE = '%type: @message in %function (line %line of %file).';
protected static $ignoredFunctions = [
'debug',
'_drupal_error_handler',
'_drupal_exception_handler',
];
public static function decodeException(\Throwable $exception) : array {
$message = $exception
->getMessage();
$backtrace = $exception
->getTrace();
array_unshift($backtrace, [
'line' => $exception
->getLine(),
'file' => $exception
->getFile(),
]);
if ($exception instanceof \PDOException || $exception instanceof DatabaseExceptionWrapper) {
$driver_namespace = Database::getConnectionInfo()['default']['namespace'];
$backtrace = Connection::removeDatabaseEntriesFromDebugBacktrace($backtrace, $driver_namespace);
if (isset($exception->query_string, $exception->args)) {
$message .= ": " . $exception->query_string . "; " . print_r($exception->args, TRUE);
}
}
$caller = static::getLastCaller($backtrace);
return [
'%type' => get_class($exception),
'@message' => $message,
'%function' => $caller['function'],
'%file' => $caller['file'],
'%line' => $caller['line'],
'severity_level' => static::ERROR,
'backtrace' => $backtrace,
'@backtrace_string' => $exception
->getTraceAsString(),
'exception' => $exception,
];
}
public static function logException(LoggerInterface $logger, \Throwable $exception, string $message = Error::DEFAULT_ERROR_MESSAGE, array $additional_variables = [], string $level = LogLevel::ERROR) : void {
$logger
->log($level, $message, static::decodeException($exception) + $additional_variables);
}
public static function renderExceptionSafe($exception) {
$decode = static::decodeException($exception);
$backtrace = $decode['backtrace'];
unset($decode['backtrace'], $decode['exception']);
array_shift($backtrace);
$decode['@backtrace'] = Error::formatBacktrace($backtrace);
return new FormattableMarkup(Error::DEFAULT_ERROR_MESSAGE . ' <pre class="backtrace">@backtrace</pre>', $decode);
}
public static function getLastCaller(array &$backtrace) {
while ($backtrace && !isset($backtrace[0]['line']) || isset($backtrace[1]['function']) && in_array($backtrace[1]['function'], static::$ignoredFunctions)) {
array_shift($backtrace);
}
$call = $backtrace[0];
if (isset($backtrace[1])) {
if (isset($backtrace[1]['class'])) {
$call['function'] = $backtrace[1]['class'] . $backtrace[1]['type'] . $backtrace[1]['function'] . '()';
}
else {
$call['function'] = $backtrace[1]['function'] . '()';
}
}
else {
$call['function'] = 'main()';
}
return $call;
}
public static function formatBacktrace(array $backtrace) {
$return = '';
foreach ($backtrace as $trace) {
$call = [
'function' => '',
'args' => [],
];
if (isset($trace['class'])) {
$call['function'] = $trace['class'] . $trace['type'] . $trace['function'];
}
elseif (isset($trace['function'])) {
$call['function'] = $trace['function'];
}
else {
$call['function'] = 'main';
}
if (isset($trace['args'])) {
foreach ($trace['args'] as $arg) {
if (is_scalar($arg)) {
$call['args'][] = is_string($arg) ? '\'' . Xss::filter($arg) . '\'' : $arg;
}
else {
$call['args'][] = ucfirst(gettype($arg));
}
}
}
$line = '';
if (isset($trace['line'])) {
$line = " (Line: {$trace['line']})";
}
$return .= $call['function'] . '(' . implode(', ', $call['args']) . "){$line}\n";
}
return $return;
}
}
Classes
Name |
Description |
Error |
Drupal error utility class. |