[wp-trac] [WordPress Trac] #59282: WordPress should register custom error and exception handlers

WordPress Trac noreply at wordpress.org
Tue Jul 1 17:50:50 UTC 2025


#59282: WordPress should register custom error and exception handlers
-------------------------------------------------+-------------------------
 Reporter:  bjorsch                              |       Owner:  (none)
     Type:  feature request                      |      Status:  new
 Priority:  normal                               |   Milestone:  Future
                                                 |  Release
Component:  Bootstrap/Load                       |     Version:  6.4
 Severity:  normal                               |  Resolution:
 Keywords:  has-patch dev-feedback needs-test-   |     Focuses:
  info                                           |
-------------------------------------------------+-------------------------

Comment (by bjorsch):

 I'm still not very clear on what you're actually asking for, but let's
 give it a try.

 The Use-Case is as described in the ticket: We want PHP error messages
 (including from uncaught exceptions) and warnings displayed in the browser
 to be properly encoded to avoid HTML injection, but escaping at the time
 the message is generated is not a good solution because (1) we can only do
 that for code we control and (2) we don't know whether the message is
 going to be displayed in a browser, or from wp-cli, or written to a log
 file, or what else. The generally recommended practice (outside of
 WordPress) is to escape at the time the value is being output, which is
 what the PR here implements.

 As for code to be used for testing, here's a simple mu-plugin to generate
 various types of errors.
 {{{#!php
 <?php

 // Set appropriate ini settings. You'll at least want to test with
 html_errors both on and off.
 // You could also do this in php.ini or the like instead of here.
 ini_set( 'display_errors', true );
 ini_set( 'html_errors', false );

 function xxx_generate_error() {
         // Set this to 'warning', 'error', 'exception', or 'internal' to
 test different kinds of error messaging.
         $test = 'internal';

         // Test error message that contains some HTML that should not be
 rendered.
         $msg = 'This is a test: <script>alert("oops");</script>';

         switch ( $test ) {
                 case 'warning':
                         // A warning. The value from `error_get_last()`
 should reflect the message above.
                         trigger_error( $msg, E_USER_WARNING );
                         error_log( var_export( error_get_last(), true ) );
                         break;

                 case 'error':
                         // An error.
                         trigger_error( $msg, E_USER_ERROR );
                         break;

                 case 'exception':
                         // An uncaught exception.
                         throw new RuntimeException( $msg );
                         break;

                 case 'internal':
                         // A warning generated by PHP itself, where we
 can't reasonably HTML-encode the input.
                         $arr = array();
                         $var = $arr[ $msg ];
                         break;
         }
 }

 // You may want to try different actions to test handling during later
 parts of the request, or even just call it directly to test handling
 during the mu-plugin load.
 add_action( 'plugins_loaded', 'xxx_generate_error' );
 }}}
 The comments indicate parts of the mu-plugin that you may want to edit to
 test different scenarios. In real life, errors and warnings would be
 generated by error cases or unintentional bugs in core, plugins, and
 themes.

 As for triggering the mu-plugin, you'd want to do so in various ways:

 1. Visit a page in a browser.
 2. Run a wp-cli command.
 3. Either of the above, but then look at what is written to `debug.log`.

 Acceptance criteria for each case are:

 1. The message is shown as text, **not** rendered as HTML.
 2. On the console, the wp-cli output of the message does not have HTML-
 style encoding.
 3. The log file does not contain HTML-style encoding either.

 WordPress's current behavior with this mu-plugin will incorrectly render
 the message as HTML for 'warning', 'error', and 'internal', and for
 'exception' too when html_errors is off.

 There may be additional triggering methods to test. For example, if we
 have API endpoints that catch and report errors as properly formatted
 responses rather than letting PHP spit out HTML or something malformed,
 those should produce output that does escaping appropriate to the output
 format rather than HTML-style encoding. For example, a JSON response might
 represent it as `"This is a test:
 \u003Cscript\u003Ealert(\"oops\");\u003C/script\u003E"` (with the client
 expected to escape it properly for however it's planning to output the
 response), not `"This is a test:
 <script>alert("oops");<\/script>"` where the client
 would have to HTML-decode it before using it in a non-HTML context.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/59282#comment:18>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list