1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-04-03 07:58:18 +02:00
phorge-phorge/src/view/widget/AphrontStackTraceView.php
Andre Klapper 59428f64ca Fix PHP 8.1 "file_exists(null)" exception rendering AphrontStackTraceView
Summary:
Passing null to `file_exists()` is deprecated behavior since PHP 8.1.
The already existing `if ($file)` check in `AphrontStackTraceView` implies that `$file` can indeed be empty.
Thus add another such check higher up in that class to avoid deprecation warnings when rendering stacktraces.

```
ERROR 8192: file_exists(): Passing null to parameter #1 ($filename) of type string is deprecated at [/var/www/html/phorge/arcanist/src/filesystem/Filesystem.php:1068];
  #0 file_exists(NULL) called at [<arcanist>/src/filesystem/Filesystem.php:1068];
  #1 Filesystem::pathExists(NULL) called at [<arcanist>/src/filesystem/Filesystem.php:1180];
  #2 Filesystem::assertExists(NULL) called at [<arcanist>/src/filesystem/Filesystem.php:1020];
  #3 Filesystem::isDescendant(NULL, string) called at [<phorge>/src/view/widget/AphrontStackTraceView.php:33];
```

Closes T15881

Test Plan: Intentionally inject an `Array to string conversion bug` in `PhabricatorEmailPreferencesSettingsPanel` (see T15881). Then visit `/settings/panel/emailpreferences/`. See the same stacktrace before and after applying this change, but see only a single line of output in DarkConsole / Error Log after applying this patch and not anymore numerous `Passing null to parameter #1 ($filename) of type string is deprecated` errors in DarkConsole / Error Log.

Reviewers: O1 Blessed Committers, speck

Reviewed By: O1 Blessed Committers, speck

Subscribers: speck, tobiaswiese, valerio.bozzolan, Matthew, Cigaryno

Maniphest Tasks: T15881

Differential Revision: https://we.phorge.it/D25728
2024-07-11 07:25:19 +02:00

108 lines
2.4 KiB
PHP

<?php
final class AphrontStackTraceView extends AphrontView {
private $trace;
public function setTrace($trace) {
$this->trace = $trace;
return $this;
}
public function render() {
$trace = $this->trace;
$libraries = PhutilBootloader::getInstance()->getAllLibraries();
// TODO: Make this configurable?
$path = 'https://we.phorge.it/diffusion/%s/browse/master/src/';
$callsigns = array(
'arcanist' => 'ARC',
'phabricator' => 'P',
);
$rows = array();
$depth = count($trace);
foreach ($trace as $part) {
$lib = null;
$file = idx($part, 'file');
if ($file !== null && $file !== '') {
$relative = $file;
foreach ($libraries as $library) {
$root = phutil_get_library_root($library);
if (Filesystem::isDescendant($file, $root)) {
$lib = $library;
$relative = Filesystem::readablePath($file, $root);
break;
}
}
}
$where = '';
if (isset($part['class'])) {
$where .= $part['class'].'::';
}
if (isset($part['function'])) {
$where .= $part['function'].'()';
}
if ($file) {
if (isset($callsigns[$lib])) {
$attrs = array('title' => $file);
if (empty($attrs['href'])) {
$attrs['href'] = sprintf($path, $callsigns[$lib]).
str_replace(DIRECTORY_SEPARATOR, '/', $relative).
'$'.$part['line'];
$attrs['target'] = '_blank';
}
$file_name = phutil_tag(
'a',
$attrs,
$relative);
} else {
$file_name = phutil_tag(
'span',
array(
'title' => $file,
),
$relative);
}
$file_name = hsprintf('%s : %d', $file_name, $part['line']);
} else {
$file_name = phutil_tag('em', array(), '(Internal)');
}
$rows[] = array(
$depth--,
$lib,
$file_name,
$where,
);
}
$table = new AphrontTableView($rows);
$table->setHeaders(
array(
pht('Depth'),
pht('Library'),
pht('File'),
pht('Where'),
));
$table->setColumnClasses(
array(
'n',
'',
'',
'wide',
));
return phutil_tag(
'div',
array(
'class' => 'exception-trace',
),
$table->render());
}
}