dev_error_stacktrace.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  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(get_class($exc)); ?></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 = $params = [];
  60. $line = null;
  61. if (isset($stack['file'], $stack['line']) && is_numeric($stack['line'])):
  62. $line = $stack['line'];
  63. $excerpt = Debugger::excerpt($stack['file'], $line, 4);
  64. endif;
  65. if (isset($stack['file'])):
  66. $file = $stack['file'];
  67. else:
  68. $file = '[internal function]';
  69. endif;
  70. if (isset($stack['function'])):
  71. if (!empty($stack['args'])):
  72. foreach ((array)$stack['args'] as $arg):
  73. $params[] = Debugger::exportVar($arg, 4);
  74. endforeach;
  75. else:
  76. $params[] = 'No arguments';
  77. endif;
  78. endif;
  79. $frameId = "{$level}-{$i}";
  80. $vendorFrame = isset($stack['file']) && strpos($stack['file'], APP) === false ? 'vendor-frame' : '';
  81. ?>
  82. <li id="stack-frame-<?= $frameId ?>" class="stack-frame <?= $vendorFrame ?>">
  83. <div class="stack-frame-header">
  84. <button data-frame-id="<?= h($frameId) ?>" class="stack-frame-toggle">
  85. &#x25BC;
  86. </button>
  87. <div class="stack-frame-header-content">
  88. <span class="stack-frame-file">
  89. <?= h(Debugger::trimPath($file)); ?>
  90. </span>
  91. <?php if ($line !== null): ?>
  92. <span class="stack-frame-line">
  93. <span class="stack-frame-label">at line</span><?= h($line) ?>
  94. </span>
  95. <?php endif ?>
  96. <span class="stack-function">
  97. <?php if (isset($stack['class']) || isset($stack['function'])): ?>
  98. <span class="stack-frame-label">in</span>
  99. <?php endif ?>
  100. <?php if (isset($stack['class'])): ?>
  101. <?= h($stack['class'] . $stack['type'] . $stack['function']) ?>
  102. <?php elseif (isset($stack['function'])): ?>
  103. <?= h($stack['function']) ?>
  104. <?php endif; ?>
  105. </span>
  106. <?php if ($line !== null): ?>
  107. <?= $this->Html->link('(edit)', Debugger::editorUrl($file, $line), ['class' => 'stack-frame-edit']); ?>
  108. <?php endif; ?>
  109. </div>
  110. </div>
  111. <div
  112. class="stack-frame-contents"
  113. id="stack-frame-details-<?= $frameId ?>"
  114. style="display: none"
  115. >
  116. <table class="code-excerpt" cellspacing="0" cellpadding="0">
  117. <?php $lineno = isset($stack['line']) && is_numeric($stack['line']) ? $stack['line'] - 4 : 0 ?>
  118. <?php foreach ($excerpt as $l => $line): ?>
  119. <tr>
  120. <td class="excerpt-number" data-number="<?= $lineno + $l ?>"></td>
  121. <td class="excerpt-line"><?= $line ?></td>
  122. </tr>
  123. <?php endforeach; ?>
  124. </table>
  125. <a href="#" class="stack-frame-args" data-target="stack-args-<?= $frameId ?>">Toggle Arguments</a>
  126. <div id="stack-args-<?= $frameId ?>" class="stack-args" style="display: none;">
  127. <?php foreach ($params as $param): ?>
  128. <div class="cake-debug"><?= $param ?></div>
  129. <?php endforeach; ?>
  130. </div>
  131. </div>
  132. </li>
  133. <?php endforeach; ?>
  134. </ul>
  135. <?php endforeach; ?>