dev_error_stacktrace.php 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. /**
  3. * Prints a stack trace for an exception
  4. *
  5. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  6. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  7. *
  8. * Licensed under The MIT License
  9. * For full copyright and license information, please see the LICENSE.txt
  10. * Redistributions of files must retain the above copyright notice.
  11. *
  12. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  13. * @link https://cakephp.org CakePHP(tm) Project
  14. * @since 4.5.0
  15. * @license https://opensource.org/licenses/mit-license.php MIT License
  16. * @var array $trace
  17. */
  18. use Cake\Error\Debugger;
  19. use function Cake\Core\h;
  20. foreach ($exceptions as $level => $exc):
  21. $parent = $exceptions[$level - 1] ?? null;
  22. $stackTrace = Debugger::getUniqueFrames($exc, $parent);
  23. $stackTrace = Debugger::formatTrace($stackTrace, [
  24. 'format' => 'array',
  25. 'args' => true,
  26. ]);
  27. if ($level != 0): ?>
  28. <div class="stack-exception-header">
  29. <span class="stack-exception-caused">Caused by</span>
  30. <span class="stack-exception-message"><?= Debugger::formatHtmlMessage($exc->getMessage()) ?></span>
  31. <span class="stack-exception-type"><?= h($exc::class); ?></span>
  32. </div>
  33. <?php endif; ?>
  34. <div class="stack-frame">
  35. <?php
  36. $line = $exc->getLine();
  37. $file = $exc->getFile();
  38. $excerpt = Debugger::excerpt($file, $line, 4);
  39. $lineno = $line ? $line - 4 : 0;
  40. ?>
  41. <span class="stack-frame-file">
  42. <?= h(Debugger::trimPath($file)); ?> at line <?= h($line) ?>
  43. </span>
  44. <?php if ($line !== null): ?>
  45. <?= $this->Html->link('(edit)', Debugger::editorUrl($file, $line), ['class' => 'stack-frame-edit']); ?>
  46. <?php endif; ?>
  47. <table class="code-excerpt" cellspacing="0" cellpadding="0">
  48. <?php foreach ($excerpt as $l => $line): ?>
  49. <tr>
  50. <td class="excerpt-number" data-number="<?= $lineno + $l ?>"></td>
  51. <td class="excerpt-line"><?= $line ?></td>
  52. </tr>
  53. <?php endforeach; ?>
  54. </table>
  55. </div>
  56. <ul class="stack-frames">
  57. <?php
  58. foreach ($stackTrace as $i => $stack):
  59. $excerpt = [];
  60. $params = [];
  61. $line = null;
  62. if (isset($stack['file'], $stack['line']) && is_numeric($stack['line'])):
  63. $line = $stack['line'];
  64. $excerpt = Debugger::excerpt($stack['file'], $line, 4);
  65. endif;
  66. if (isset($stack['file'])):
  67. $file = $stack['file'];
  68. else:
  69. $file = '[internal function]';
  70. endif;
  71. if (isset($stack['function'])):
  72. if (!empty($stack['args'])):
  73. foreach ((array)$stack['args'] as $arg):
  74. $params[] = Debugger::exportVar($arg, 4);
  75. endforeach;
  76. else:
  77. $params[] = 'No arguments';
  78. endif;
  79. endif;
  80. $frameId = "{$level}-{$i}";
  81. $activeFrame = $i == 0;
  82. $vendorFrame = isset($stack['file']) && str_starts_with($stack['file'], ROOT . DS . 'vendor') ? 'vendor-frame' : '';
  83. ?>
  84. <li id="stack-frame-<?= $frameId ?>" class="stack-frame <?= $vendorFrame ?>">
  85. <div class="stack-frame-header">
  86. <button data-frame-id="<?= h($frameId) ?>" class="stack-frame-toggle">
  87. &#x25BC;
  88. </button>
  89. <div class="stack-frame-header-content">
  90. <span class="stack-frame-file">
  91. <?= h(Debugger::trimPath($file)); ?>
  92. </span>
  93. <?php if ($line !== null): ?>
  94. <span class="stack-frame-line">
  95. <span class="stack-frame-label">at line</span><?= h($line) ?>
  96. </span>
  97. <?php endif ?>
  98. <span class="stack-function">
  99. <?php if (isset($stack['class']) || isset($stack['function'])): ?>
  100. <span class="stack-frame-label">in</span>
  101. <?php endif ?>
  102. <?php if (isset($stack['class'])): ?>
  103. <?= h($stack['class'] . $stack['type'] . $stack['function']) ?>
  104. <?php elseif (isset($stack['function'])): ?>
  105. <?= h($stack['function']) ?>
  106. <?php endif; ?>
  107. </span>
  108. <?php if ($line !== null): ?>
  109. <?= $this->Html->link('(edit)', Debugger::editorUrl($file, $line), ['class' => 'stack-frame-edit']); ?>
  110. <?php endif; ?>
  111. </div>
  112. </div>
  113. <div
  114. class="stack-frame-contents"
  115. id="stack-frame-details-<?= $frameId ?>"
  116. style="display: none"
  117. >
  118. <table class="code-excerpt" cellspacing="0" cellpadding="0">
  119. <?php $lineno = isset($stack['line']) && is_numeric($stack['line']) ? $stack['line'] - 4 : 0 ?>
  120. <?php foreach ($excerpt as $l => $line): ?>
  121. <tr>
  122. <td class="excerpt-number" data-number="<?= $lineno + $l ?>"></td>
  123. <td class="excerpt-line"><?= $line ?></td>
  124. </tr>
  125. <?php endforeach; ?>
  126. </table>
  127. <a href="#" class="stack-frame-args" data-target="stack-args-<?= $frameId ?>">Toggle Arguments</a>
  128. <div id="stack-args-<?= $frameId ?>" class="stack-args" style="display: none;">
  129. <?php foreach ($params as $param): ?>
  130. <div class="cake-debug"><?= $param ?></div>
  131. <?php endforeach; ?>
  132. </div>
  133. </div>
  134. </li>
  135. <?php endforeach; ?>
  136. </ul>
  137. <?php endforeach; ?>