equal
deleted
inserted
replaced
1 <?php |
1 <?php |
2 /** |
2 /** |
3 * Error Protection API: WP_Fatal_Error_Handler class |
3 * Error Protection API: WP_Fatal_Error_Handler class |
4 * |
4 * |
5 * @package WordPress |
5 * @package WordPress |
6 * @since 5.2.0 |
6 * @since 5.2.0 |
7 */ |
7 */ |
8 |
8 |
9 /** |
9 /** |
10 * Core class used as the default shutdown handler for fatal errors. |
10 * Core class used as the default shutdown handler for fatal errors. |
11 * |
11 * |
28 public function handle() { |
28 public function handle() { |
29 if ( defined( 'WP_SANDBOX_SCRAPING' ) && WP_SANDBOX_SCRAPING ) { |
29 if ( defined( 'WP_SANDBOX_SCRAPING' ) && WP_SANDBOX_SCRAPING ) { |
30 return; |
30 return; |
31 } |
31 } |
32 |
32 |
|
33 // Do not trigger the fatal error handler while updates are being installed. |
|
34 if ( wp_is_maintenance_mode() ) { |
|
35 return; |
|
36 } |
|
37 |
33 try { |
38 try { |
34 // Bail if no error found. |
39 // Bail if no error found. |
35 $error = $this->detect_error(); |
40 $error = $this->detect_error(); |
36 if ( ! $error ) { |
41 if ( ! $error ) { |
37 return; |
42 return; |
39 |
44 |
40 if ( ! isset( $GLOBALS['wp_locale'] ) && function_exists( 'load_default_textdomain' ) ) { |
45 if ( ! isset( $GLOBALS['wp_locale'] ) && function_exists( 'load_default_textdomain' ) ) { |
41 load_default_textdomain(); |
46 load_default_textdomain(); |
42 } |
47 } |
43 |
48 |
|
49 $handled = false; |
|
50 |
44 if ( ! is_multisite() && wp_recovery_mode()->is_initialized() ) { |
51 if ( ! is_multisite() && wp_recovery_mode()->is_initialized() ) { |
45 wp_recovery_mode()->handle_error( $error ); |
52 $handled = wp_recovery_mode()->handle_error( $error ); |
46 } |
53 } |
47 |
54 |
48 // Display the PHP error template if headers not sent. |
55 // Display the PHP error template if headers not sent. |
49 if ( is_admin() || ! headers_sent() ) { |
56 if ( is_admin() || ! headers_sent() ) { |
50 $this->display_error_template( $error ); |
57 $this->display_error_template( $error, $handled ); |
51 } |
58 } |
52 } catch ( Exception $e ) { |
59 } catch ( Exception $e ) { |
53 // Catch exceptions and remain silent. |
60 // Catch exceptions and remain silent. |
54 } |
61 } |
55 } |
62 } |
123 * `wp-includes/load.php` should be checked for before being called. |
130 * `wp-includes/load.php` should be checked for before being called. |
124 * |
131 * |
125 * If no such drop-in is available, this will call {@see WP_Fatal_Error_Handler::display_default_error_template()}. |
132 * If no such drop-in is available, this will call {@see WP_Fatal_Error_Handler::display_default_error_template()}. |
126 * |
133 * |
127 * @since 5.2.0 |
134 * @since 5.2.0 |
128 * |
135 * @since 5.3.0 The `$handled` parameter was added. |
129 * @param array $error Error information retrieved from `error_get_last()`. |
136 * |
130 */ |
137 * @param array $error Error information retrieved from `error_get_last()`. |
131 protected function display_error_template( $error ) { |
138 * @param true|WP_Error $handled Whether Recovery Mode handled the fatal error. |
|
139 */ |
|
140 protected function display_error_template( $error, $handled ) { |
132 if ( defined( 'WP_CONTENT_DIR' ) ) { |
141 if ( defined( 'WP_CONTENT_DIR' ) ) { |
133 // Load custom PHP error template, if present. |
142 // Load custom PHP error template, if present. |
134 $php_error_pluggable = WP_CONTENT_DIR . '/php-error.php'; |
143 $php_error_pluggable = WP_CONTENT_DIR . '/php-error.php'; |
135 if ( is_readable( $php_error_pluggable ) ) { |
144 if ( is_readable( $php_error_pluggable ) ) { |
136 require_once $php_error_pluggable; |
145 require_once $php_error_pluggable; |
138 return; |
147 return; |
139 } |
148 } |
140 } |
149 } |
141 |
150 |
142 // Otherwise, display the default error template. |
151 // Otherwise, display the default error template. |
143 $this->display_default_error_template( $error ); |
152 $this->display_default_error_template( $error, $handled ); |
144 } |
153 } |
145 |
154 |
146 /** |
155 /** |
147 * Displays the default PHP error template. |
156 * Displays the default PHP error template. |
148 * |
157 * |
151 * It calls {@see wp_die()} with a message indicating that the site is experiencing technical difficulties and a |
160 * It calls {@see wp_die()} with a message indicating that the site is experiencing technical difficulties and a |
152 * login link to the admin backend. The {@see 'wp_php_error_message'} and {@see 'wp_php_error_args'} filters can |
161 * login link to the admin backend. The {@see 'wp_php_error_message'} and {@see 'wp_php_error_args'} filters can |
153 * be used to modify these parameters. |
162 * be used to modify these parameters. |
154 * |
163 * |
155 * @since 5.2.0 |
164 * @since 5.2.0 |
156 * |
165 * @since 5.3.0 The `$handled` parameter was added. |
157 * @param array $error Error information retrieved from `error_get_last()`. |
166 * |
158 */ |
167 * @param array $error Error information retrieved from `error_get_last()`. |
159 protected function display_default_error_template( $error ) { |
168 * @param true|WP_Error $handled Whether Recovery Mode handled the fatal error. |
|
169 */ |
|
170 protected function display_default_error_template( $error, $handled ) { |
160 if ( ! function_exists( '__' ) ) { |
171 if ( ! function_exists( '__' ) ) { |
161 wp_load_translations_early(); |
172 wp_load_translations_early(); |
162 } |
173 } |
163 |
174 |
164 if ( ! function_exists( 'wp_die' ) ) { |
175 if ( ! function_exists( 'wp_die' ) ) { |
167 |
178 |
168 if ( ! class_exists( 'WP_Error' ) ) { |
179 if ( ! class_exists( 'WP_Error' ) ) { |
169 require_once ABSPATH . WPINC . '/class-wp-error.php'; |
180 require_once ABSPATH . WPINC . '/class-wp-error.php'; |
170 } |
181 } |
171 |
182 |
172 if ( is_protected_endpoint() ) { |
183 if ( true === $handled && wp_is_recovery_mode() ) { |
173 $message = __( 'The site is experiencing technical difficulties. Please check your site admin email inbox for instructions.' ); |
184 $message = __( 'There has been a critical error on your website, putting it in recovery mode. Please check the Themes and Plugins screens for more details. If you just installed or updated a theme or plugin, check the relevant page for that first.' ); |
|
185 } elseif ( is_protected_endpoint() ) { |
|
186 $message = __( 'There has been a critical error on your website. Please check your site admin email inbox for instructions.' ); |
174 } else { |
187 } else { |
175 $message = __( 'The site is experiencing technical difficulties.' ); |
188 $message = __( 'There has been a critical error on your website.' ); |
176 } |
189 } |
|
190 |
|
191 $message = sprintf( |
|
192 '<p>%s</p><p><a href="%s">%s</a></p>', |
|
193 $message, |
|
194 /* translators: Documentation explaining debugging in WordPress. */ |
|
195 __( 'https://wordpress.org/support/article/debugging-in-wordpress/' ), |
|
196 __( 'Learn more about debugging in WordPress.' ) |
|
197 ); |
177 |
198 |
178 $args = array( |
199 $args = array( |
179 'response' => 500, |
200 'response' => 500, |
180 'exit' => false, |
201 'exit' => false, |
181 ); |
202 ); |