Browse Source

Fix missing stack frame in error pages

Exceptions in PHP don't include the frame that the error originated from
in the result of Exception::getTrace(). To workaround that we need to
use the exception's file & line attributes as an additional frame.

Fixes #13869
Mark Story 6 years ago
parent
commit
2c880d4527

+ 9 - 3
src/Error/ExceptionRenderer.php

@@ -206,12 +206,18 @@ class ExceptionRenderer implements ExceptionRendererInterface
 
         $isDebug = Configure::read('debug');
         if ($isDebug) {
-            $viewVars['trace'] = Debugger::formatTrace($exception->getTrace(), [
+            $trace = Debugger::formatTrace($exception->getTrace(), [
                 'format' => 'array',
                 'args' => false,
             ]);
-            $viewVars['file'] = $exception->getFile() ?: 'null';
-            $viewVars['line'] = $exception->getLine() ?: 'null';
+            $origin = [
+                'file' => $exception->getFile() ?: 'null',
+                'line' => $exception->getLine() ?: 'null',
+            ];
+            // Traces don't include the origin file/line.
+            array_unshift($trace, $origin);
+            $viewVars['trace'] = $trace;
+            $viewVars += $origin;
             $serialize[] = 'file';
             $serialize[] = 'line';
         }

+ 2 - 4
templates/element/exception_stack_trace.php

@@ -15,10 +15,8 @@
  * @license       https://opensource.org/licenses/mit-license.php MIT License
  */
 use Cake\Error\Debugger;
-?>
 
-<?php
-foreach ($error->getTrace() as $i => $stack):
+foreach ($trace as $i => $stack):
     $excerpt = $params = [];
 
     if (isset($stack['file'], $stack['line'])):
@@ -31,7 +29,7 @@ foreach ($error->getTrace() as $i => $stack):
         $file = '[internal function]';
     endif;
 
-    if ($stack['function']):
+    if (isset($stack['function'])):
         if (!empty($stack['args'])):
             foreach ((array)$stack['args'] as $arg):
                 $params[] = Debugger::exportVar($arg, 4);

+ 2 - 6
templates/element/exception_stack_trace_nav.php

@@ -17,17 +17,16 @@ use Cake\Error\Debugger;
 <a href="#" class="toggle-link toggle-vendor-frames">Toggle Vendor Stack Frames</a>
 
 <ul class="stack-trace">
-<?php foreach ($error->getTrace() as $i => $stack): ?>
+<?php foreach ($trace as $i => $stack): ?>
     <?php
     $class = isset($stack['file']) && strpos($stack['file'], APP) === false ? 'vendor-frame' : 'app-frame';
     $class .= $i == 0 ? ' active' : '';
     ?>
     <li class="stack-frame <?= $class ?>">
-    <?php if (isset($stack['function'])): ?>
         <a href="#" data-target="stack-frame-<?= $i ?>">
             <?php if (isset($stack['class'])): ?>
                 <span class="stack-function"><?= h($stack['class'] . $stack['type'] . $stack['function']) ?></span>
-            <?php else: ?>
+            <?php elseif (isset($stack['function'])): ?>
                 <span class="stack-function"><?= h($stack['function']) ?></span>
             <?php endif; ?>
             <span class="stack-file">
@@ -38,9 +37,6 @@ use Cake\Error\Debugger;
             <?php endif ?>
             </span>
         </a>
-    <?php else: ?>
-        <a href="#">&rang; [internal function]</a>
-    <?php endif; ?>
     </li>
 <?php endforeach; ?>
 </ul>