{"id":5617,"date":"2026-02-12T20:44:56","date_gmt":"2026-02-13T01:44:56","guid":{"rendered":"https:\/\/chubes.net\/?documentation=wp_fatal_error_handler"},"modified":"2026-03-13T03:28:23","modified_gmt":"2026-03-13T07:28:23","slug":"wp_fatal_error_handler","status":"publish","type":"documentation","link":"https:\/\/chubes.net\/docs\/wordpress-core\/errors\/wp_fatal_error_handler\/","title":{"rendered":"WP_Fatal_Error_Handler"},"content":{"rendered":"<p>Default shutdown handler for fatal PHP errors.<\/p><p><strong>Source:<\/strong> <code>wp-includes\/class-wp-fatal-error-handler.php<\/code><br \/>\n<strong>Since:<\/strong> 5.2.0<\/p><h2 class=\"wp-block-heading\">Description<\/h2><p><code>WP_Fatal_Error_Handler<\/code> handles fatal PHP errors that would normally cause a &quot;white screen of death&quot; (WSOD). It provides user-friendly error messages and integrates with WordPress Recovery Mode.<\/p><p>A drop-in <code>fatal-error-handler.php<\/code> in <code>wp-content\/<\/code> can provide a custom handler class.<\/p><h2 class=\"wp-block-heading\">Class Attributes<\/h2><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">#[AllowDynamicProperties]\nclass WP_Fatal_Error_Handler<\/code><\/pre><\/div><h2 class=\"wp-block-heading\">How It Works<\/h2><ol class=\"wp-block-list\"><li>Registered via <code>register_shutdown_function()<\/code> during WordPress bootstrap<\/li><li>When PHP encounters a fatal error, the shutdown function runs<\/li><li>Handler detects the error, checks if it should be handled<\/li><li>Attempts Recovery Mode for protected endpoints<\/li><li>Displays appropriate error template<\/li><\/ol><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Methods<\/h2><h3 class=\"wp-block-heading\">handle()<\/h3><p>Runs the shutdown handler. Registered via <code>register_shutdown_function()<\/code>.<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">public function handle(): void<\/code><\/pre><\/div><p><strong>Flow:<\/strong><\/p><ol class=\"wp-block-list\"><li>Exit early if <code>WP_SANDBOX_SCRAPING<\/code> is defined<\/li><li>Exit early if in maintenance mode<\/li><li>Detect error via <code>detect_error()<\/code><\/li><li>Load text domain if needed<\/li><li>Attempt Recovery Mode handling (single site, initialized)<\/li><li>Display error template if admin or headers not sent<\/li><\/ol><p><strong>Example registration:<\/strong><\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">\/\/ Done automatically by wp_register_fatal_error_handler()\nregister_shutdown_function( array( $handler, &#039;handle&#039; ) );<\/code><\/pre><\/div><hr class=\"wp-block-separator\"\/><h3 class=\"wp-block-heading\">detect_error() (protected)<\/h3><p>Detects the error causing the crash.<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">protected function detect_error(): ?array<\/code><\/pre><\/div><p><strong>Returns:<\/strong> Error array from <code>error_get_last()<\/code>, or <code>null<\/code> if no error or error shouldn&#8217;t be handled.<\/p><p><strong>Error array structure:<\/strong><\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">array(\n    &#039;type&#039;    =&gt; E_ERROR,           \/\/ Error type constant\n    &#039;message&#039; =&gt; &#039;Error message&#039;,   \/\/ Error description\n    &#039;file&#039;    =&gt; &#039;\/path\/to\/file.php&#039;,\n    &#039;line&#039;    =&gt; 123,\n)<\/code><\/pre><\/div><hr class=\"wp-block-separator\"\/><h3 class=\"wp-block-heading\">should_handle_error() (protected)<\/h3><p>Determines whether WordPress should handle the error.<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">protected function should_handle_error( array $error ): bool<\/code><\/pre><\/div><figure class=\"wp-block-table\"><table><thead><tr><th>Parameter<\/th><th>Type<\/th><th>Required<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><code>$error<\/code><\/td><td>array<\/td><td>Yes<\/td><td>Error from <code>error_get_last()<\/code><\/td><\/tr><\/tbody><\/table><\/figure><p><strong>Returns:<\/strong> <code>true<\/code> if WordPress should handle the error.<\/p><p><strong>Handled error types:<\/strong><\/p><figure class=\"wp-block-table\"><table><thead><tr><th>Constant<\/th><th>Value<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><code>E_ERROR<\/code><\/td><td>1<\/td><td>Fatal run-time error<\/td><\/tr><tr><td><code>E_PARSE<\/code><\/td><td>4<\/td><td>Compile-time parse error<\/td><\/tr><tr><td><code>E_USER_ERROR<\/code><\/td><td>256<\/td><td>User-generated fatal error<\/td><\/tr><tr><td><code>E_COMPILE_ERROR<\/code><\/td><td>64<\/td><td>Fatal compile-time error<\/td><\/tr><tr><td><code>E_RECOVERABLE_ERROR<\/code><\/td><td>4096<\/td><td>Catchable fatal error<\/td><\/tr><\/tbody><\/table><\/figure><p>Additional errors can be included via the <code>wp_should_handle_php_error<\/code> filter.<\/p><hr class=\"wp-block-separator\"\/><h3 class=\"wp-block-heading\">display_error_template() (protected)<\/h3><p>Displays the PHP error template.<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">protected function display_error_template( array $error, true|WP_Error $handled ): void<\/code><\/pre><\/div><figure class=\"wp-block-table\"><table><thead><tr><th>Parameter<\/th><th>Type<\/th><th>Required<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><code>$error<\/code><\/td><td>array<\/td><td>Yes<\/td><td>Error from <code>error_get_last()<\/code><\/td><\/tr><tr><td><code>$handled<\/code><\/td><td>true|WP_Error<\/td><td>Yes<\/td><td>Whether Recovery Mode handled the error<\/td><\/tr><\/tbody><\/table><\/figure><p><strong>Template priority:<\/strong><\/p><ol class=\"wp-block-list\"><li>Custom drop-in: <code>wp-content\/php-error.php<\/code><\/li><li>Default template via <code>display_default_error_template()<\/code><\/li><\/ol><hr class=\"wp-block-separator\"\/><h3 class=\"wp-block-heading\">display_default_error_template() (protected)<\/h3><p>Displays the default PHP error template using <code>wp_die()<\/code>.<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">protected function display_default_error_template( array $error, true|WP_Error $handled ): void<\/code><\/pre><\/div><figure class=\"wp-block-table\"><table><thead><tr><th>Parameter<\/th><th>Type<\/th><th>Required<\/th><th>Description<\/th><\/tr><\/thead><tbody><tr><td><code>$error<\/code><\/td><td>array<\/td><td>Yes<\/td><td>Error from <code>error_get_last()<\/code><\/td><\/tr><tr><td><code>$handled<\/code><\/td><td>true|WP_Error<\/td><td>Yes<\/td><td>Whether Recovery Mode handled the error<\/td><\/tr><\/tbody><\/table><\/figure><p><strong>Messages by context:<\/strong><\/p><figure class=\"wp-block-table\"><table><thead><tr><th>Context<\/th><th>Message<\/th><\/tr><\/thead><tbody><tr><td>Recovery Mode active<\/td><td>&quot;&#8230;putting it in recovery mode. Please check Themes and Plugins&#8230;&quot;<\/td><\/tr><tr><td>Protected endpoint (multisite)<\/td><td>&quot;&#8230;reach out to your site administrator&#8230;&quot;<\/td><\/tr><tr><td>Protected endpoint (single)<\/td><td>&quot;&#8230;check your site admin email inbox&#8230;&quot;<\/td><\/tr><tr><td>Other<\/td><td>&quot;There has been a critical error on this website.&quot;<\/td><\/tr><\/tbody><\/table><\/figure><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Customization<\/h2><h3 class=\"wp-block-heading\">Custom Fatal Error Handler (Drop-in)<\/h3><p>Create <code>wp-content\/fatal-error-handler.php<\/code>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">&lt;?php\nclass My_Fatal_Error_Handler extends WP_Fatal_Error_Handler {\n    \n    protected function display_default_error_template( $error, $handled ) {\n        \/\/ Custom error display\n        http_response_code( 500 );\n        echo &#039;&lt;h1&gt;Site Temporarily Unavailable&lt;\/h1&gt;&#039;;\n        echo &#039;&lt;p&gt;We are experiencing technical difficulties.&lt;\/p&gt;&#039;;\n        \n        \/\/ Log the actual error\n        error_log( sprintf(\n            &#039;Fatal error: %s in %s on line %d&#039;,\n            $error[&#039;message&#039;],\n            $error[&#039;file&#039;],\n            $error[&#039;line&#039;]\n        ) );\n    }\n}\n\nreturn new My_Fatal_Error_Handler();<\/code><\/pre><\/div><h3 class=\"wp-block-heading\">Custom PHP Error Template (Drop-in)<\/h3><p>Create <code>wp-content\/php-error.php<\/code>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">&lt;?php\n\/**\n * Custom PHP error template.\n * \n * Variables available:\n * - $error: Error array from error_get_last()\n * - $handled: Whether Recovery Mode handled the error\n *\/\nhttp_response_code( 500 );\n?&gt;\n&lt;!DOCTYPE html&gt;\n&lt;html&gt;\n&lt;head&gt;\n    &lt;title&gt;Error&lt;\/title&gt;\n&lt;\/head&gt;\n&lt;body&gt;\n    &lt;h1&gt;Something went wrong&lt;\/h1&gt;\n    &lt;p&gt;Please try again later.&lt;\/p&gt;\n&lt;\/body&gt;\n&lt;\/html&gt;<\/code><\/pre><\/div><h3 class=\"wp-block-heading\">Disabling the Handler<\/h3><p>Via constant in <code>wp-config.php<\/code>:<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">define( &#039;WP_DISABLE_FATAL_ERROR_HANDLER&#039;, true );<\/code><\/pre><\/div><p>Via filter (must be defined before WordPress loads):<\/p><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">$GLOBALS[&#039;wp_filter&#039;] = array(\n    &#039;wp_fatal_error_handler_enabled&#039; =&gt; array(\n        10 =&gt; array(\n            array(\n                &#039;accepted_args&#039; =&gt; 0,\n                &#039;function&#039;      =&gt; function() {\n                    return false;\n                },\n            ),\n        ),\n    ),\n);<\/code><\/pre><\/div><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Integration with Recovery Mode<\/h2><p>When a fatal error occurs on a protected endpoint:<\/p><ol class=\"wp-block-list\"><li>Error is detected by <code>WP_Fatal_Error_Handler<\/code><\/li><li><code>wp_recovery_mode()-&gt;handle_error()<\/code> is called<\/li><li>Recovery Mode:<ul class=\"wp-block-list\"><li>Logs the error<\/li><li>Identifies the problematic extension<\/li><li>Pauses the extension<\/li><li>Sends recovery email to admin<\/li><\/ul><\/li><li>Admin can access site via recovery link<\/li><li>Admin can fix or deactivate the extension<\/li><\/ol><p><strong>Protected endpoints:<\/strong><\/p><ul class=\"wp-block-list\"><li>Logs the error<\/li><li>Identifies the problematic extension<\/li><li>Pauses the extension<\/li><li>Sends recovery email to admin<\/li><\/ul><hr class=\"wp-block-separator\"\/><h2 class=\"wp-block-heading\">Error Handling Flow<\/h2><div class=\"code-block-wrapper\"><div class=\"code-block-header\"><span class=\"code-block-language\">php<\/span><button class=\"code-copy-btn\" aria-label=\"Copy code\"><svg><use href=\"https:\/\/chubes.net\/wp-content\/themes\/chubes\/assets\/icons\/chubes.svg#icon-copy\"><\/use><\/svg><\/button><\/div><pre data-chubes-enhanced class=\"wp-block-code language-php\"><code class=\"language-php\">PHP Fatal Error\n    \u2502\n    \u25bc\nregister_shutdown_function() triggers\n    \u2502\n    \u25bc\nWP_Fatal_Error_Handler::handle()\n    \u2502\n    \u251c\u2500\u2500 WP_SANDBOX_SCRAPING? \u2192 exit\n    \u251c\u2500\u2500 Maintenance mode? \u2192 exit\n    \u2502\n    \u25bc\ndetect_error()\n    \u2502\n    \u251c\u2500\u2500 No error? \u2192 exit\n    \u251c\u2500\u2500 should_handle_error() = false? \u2192 exit\n    \u2502\n    \u25bc\nRecovery Mode initialized?\n    \u2502\n    \u251c\u2500\u2500 Yes \u2192 wp_recovery_mode()-&gt;handle_error()\n    \u2502         \u2514\u2500\u2500 Pause extension, send email\n    \u2502\n    \u25bc\ndisplay_error_template()\n    \u2502\n    \u251c\u2500\u2500 php-error.php drop-in exists?\n    \u2502   \u2514\u2500\u2500 Yes \u2192 require php-error.php\n    \u2502\n    \u2514\u2500\u2500 No \u2192 display_default_error_template()\n             \u2514\u2500\u2500 wp_die() with error message<\/code><\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>Default shutdown handler for fatal PHP errors. Source: wp-includes\/class-wp-fatal-error-handler.php Since: 5.2.0 Description WP_Fatal_Error_Handler handles fatal PHP errors that would normally cause a &quot;white screen of death&quot; (WSOD). It provides user-friendly&#8230;<\/p>\n","protected":false},"featured_media":0,"template":"","meta":{"footnotes":""},"tags":[],"project":[621],"project_type":[749],"class_list":["post-5617","documentation","type-documentation","status-publish","hentry","project-errors","project_type-wordpress-reference"],"project_info":{"id":589,"name":"WordPress Core","slug":"wordpress-core"},"project_type_info":{"id":749,"name":"WordPress Reference","slug":"wordpress-reference"},"_links":{"self":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/5617","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation"}],"about":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/types\/documentation"}],"version-history":[{"count":17,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/5617\/revisions"}],"predecessor-version":[{"id":10896,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/documentation\/5617\/revisions\/10896"}],"wp:attachment":[{"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/media?parent=5617"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/tags?post=5617"},{"taxonomy":"project","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/project?post=5617"},{"taxonomy":"project_type","embeddable":true,"href":"https:\/\/chubes.net\/wp-json\/wp\/v2\/project_type?post=5617"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}