Browse Source

Format dev error messages

Apply a few simple HTML formatting transforms to error messages. This
should help make error pages easier to understand and gives us more
options when writing verbose error messages.
Mark Story 6 years ago
parent
commit
dfa3c6ccbe
3 changed files with 45 additions and 1 deletions
  1. 23 0
      src/Error/Debugger.php
  2. 2 1
      templates/layout/dev_error.php
  3. 20 0
      tests/TestCase/Error/DebuggerTest.php

+ 23 - 0
src/Error/Debugger.php

@@ -930,6 +930,29 @@ TEXT;
     }
 
     /**
+     * Format an exception message to be HTML formatted.
+     *
+     * Does the following formatting operations:
+     *
+     * - HTML escape the message.
+     * - Convert `bool` into `<code>bool</code>`
+     * - Convert newlines into `<br />`
+     *
+     * @param string $message The string message to format.
+     * @return string Formatted message.
+     */
+    public static function formatHtmlMessage(string $message): string
+    {
+        $message = h($message);
+        $message = preg_replace_callback('/`([^`]+)`/', function ($matches) {
+            return '<code>' . $matches[1] . '</code>';
+        }, $message);
+        $message = nl2br($message);
+
+        return $message;
+    }
+
+    /**
      * Verifies that the application's salt and cipher seed value has been changed from the default value.
      *
      * @return void

+ 2 - 1
templates/layout/dev_error.php

@@ -12,6 +12,7 @@
  * @since         3.0.0
  * @license       https://opensource.org/licenses/mit-license.php MIT License
  */
+use Cake\Error\Debugger;
 ?>
 <!DOCTYPE html>
 <html>
@@ -19,7 +20,7 @@
     <?= $this->Html->charset() ?>
     <meta name="viewport" content="width=device-width, initial-scale=1.0">
     <title>
-        Error: <?= h($this->fetch('title')) ?>
+        Error: <?= Debugger::formatHtmlMessage($this->fetch('title')) ?>
     </title>
     <?= $this->Html->meta('icon') ?>
     <style>

+ 20 - 0
tests/TestCase/Error/DebuggerTest.php

@@ -825,4 +825,24 @@ EXPECTED;
         $expected = sprintf($expected, str_replace(CAKE_CORE_INCLUDE_PATH, '', __FILE__), __LINE__ - 9);
         $this->assertEquals($expected, $result);
     }
+
+    /**
+     * test formatHtmlMessage
+     *
+     * @return void
+     */
+    public function formatHtmlMessage()
+    {
+        $output = Debugger::formatHtmlMessage('Some `code` to `replace`');
+        $this->assertSame('Some <code>code</code> to <code>replace</code>', $output);
+
+        $output = Debugger::formatHtmlMessage('Some `co\nde` to `replace`\nmore');
+        $this->assertSame('Some <code>co<br>de</code> to <code>replace</code><br>more', $output);
+
+        $output = Debugger::formatHtmlMessage('Some `code` to <script>alert("test")</script>\nmore');
+        $this->assertSame(
+            'Some <code>co<br>de</code> to &lt;script&gt;alert(&quot;test&quot;&lt;/script&gt;<br>more',
+            $output
+        );
+    }
 }