<p>I'm taking the leap: my PHP scripts will ALL fail gracefully!</p>

<p>At least, that's what I'm hoping for...`</p>

<p>I don't want to wrap (practically) every single line in <code>try...catch</code> statements, so I think my best bet is to make a custom error handler for the beginning of my files.</p>

<p>I'm testing it out on a practice page:</p>

<pre><code>function customError($level,$message,$file,$line,$context) {
    echo "Sorry, an error has occured on line $line.&lt;br /&gt;";
    echo "The function that caused the error says $message.&lt;br /&gt;";
    die();
}

set_error_handler("customError");

echo($imAFakeVariable);
</code></pre>

<p>This works fine, returning:</p>

<blockquote>
  <p>Sorry, an error has occurred on line 17. The function that caused the
  error says Undefined variable: imAFakeVariable.</p>
</blockquote>

<p>However, this setup doesn't work for undefined functions.</p>

<pre><code>function customError($level,$message,$file,$line,$context) {
    echo "Sorry, an error has occured on line $line.&lt;br /&gt;";
    echo "The function that caused the error says $message.&lt;br /&gt;";
    die();
}

set_error_handler("customError");

imAFakeFunction();
</code></pre>

<p>This returns:</p>

<blockquote>
  <p>Fatal error: Call to undefined function: imafakefunction() in
  /Library/WebServer/Documents/experimental/errorhandle.php on line 17</p>
</blockquote>

<p>Why isn't my custom error handler catching undefined functions?  Are there other problems that this will cause?</p>

[{'answer_id': 36625, 'author': 'John Millikin', 'author_id': 3560, 'author_profile': 'https://Stackoverflow.com/users/3560', 'pm_score': 1, 'selected': False, 'text': "<blockquote>\n  <p>Why isn't my custom error handler catching undefinedd functions? Are there other problems that this will cause?</p>\n</blockquote>\n\n<p>At a guess, I'd say that undefined function errors travel through a different execution path than other error types. Perhaps the PHP designers could tell you more, except I doubt PHP is in any way designed.</p>\n\n<p>If you'd like your scripts to fail gracefully while still writing them PHP-style, try putting the entire page in a function and then call it within a <code>try..catch</code> block.</p>\n"}, {'answer_id': 36704, 'author': 'Grey Panther', 'author_id': 1265, 'author_profile': 'https://Stackoverflow.com/users/1265', 'pm_score': 2, 'selected': False, 'text': '<p>From the <a href="http://php.net/set_error_handler" rel="nofollow noreferrer">documentation</a> (emphasis added):</p>\n\n<blockquote>\n  <p>The following error types <strong>cannot</strong> be handled with a user defined function: E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING, E_COMPILE_ERROR, E_COMPILE_WARNING, and most of E_STRICT raised in the file where set_error_handler() is called.</p>\n</blockquote>\n\n<p>Calling undefined functions triggers an E_ERROR, thus it can not be handled by the error callback (or by exception handlers for that matter). All that you can do is set error_reporting to 0.</p>\n\n<p>PS, if you are rolling your own error handler, you should take care to handle correctly the @ operator. From the documentation (emphasis added):</p>\n\n<blockquote>\n  <p>It is important to remember that the standard PHP error handler is completely bypassed. error_reporting() settings will have no effect and your error handler will be called regardless - however you are still able to read the current value of error_reporting and act appropriately. <strong>Of particular note is that this value will be 0 if the statement that caused the error was prepended by the @ error-control operator.</strong></p>\n</blockquote>\n'}, {'answer_id': 36705, 'author': 'Ross', 'author_id': 2025, 'author_profile': 'https://Stackoverflow.com/users/2025', 'pm_score': 5, 'selected': True, 'text': '<p><code>set_error_handler</code> is designed to handle errors with codes of: <code>E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE</code>. This is because <code>set_error_handler</code> is meant to be a method of reporting errors thrown by the <em>user</em> error function <code>trigger_error</code>.</p>\n\n<p>However, I did find this comment in the manual that may help you:</p>\n\n<blockquote>\n  <p>"The following error types cannot be handled with a user defined function: <code>E_ERROR</code>, <code>E_PARSE</code>, <code>E_CORE_ERROR</code>, <code>E_CORE_WARNING</code>, <code>E_COMPILE_ERROR</code>, <code>E_COMPILE_WARNING</code>, and most of <code>E_STRICT</code> raised in the file where <code>set_error_handler()</code> is called."</p>\n  \n  <p>This is not exactly true.  <code>set_error_handler()</code> can\'t handle them, but <code>ob_start()</code> can handle at least <code>E_ERROR</code>.</p>\n\n<pre><code>&lt;?php\n\nfunction error_handler($output)\n{\n    $error = error_get_last();\n    $output = "";\n    foreach ($error as $info =&gt; $string)\n        $output .= "{$info}: {$string}\\n";\n    return $output;\n}\n\nob_start(\'error_handler\');\n\nwill_this_undefined_function_raise_an_error();\n\n?&gt;\n</code></pre>\n</blockquote>\n\n<p>Really though these errors should be silently reported in a file, for example. Hopefully you won\'t have many <code>E_PARSE</code> errors in your project! :-)</p>\n\n<p>As for general error reporting, stick with Exceptions (I find it helpful to make them tie in with my MVC system). You can build a pretty versatile Exception to provide options via buttons and add plenty of description to let the user know what\'s wrong.</p>\n'}, {'answer_id': 5471570, 'author': 'ShRi Ram', 'author_id': 681921, 'author_profile': 'https://Stackoverflow.com/users/681921', 'pm_score': 3, 'selected': False, 'text': "<p>I guess you needs to use <code>register_shutdown_function</code> also</p>\n\n<p>For example:</p>\n\n<pre><code> register_shutdown_function( array( $this, 'customError' ));.\n\n   function customError() \n   {\n\n     $arrStrErrorInfo = error_get_last();\n\n     print_r( $arrStrErrorInfo );\n\n   }\n</code></pre>\n"}, {'answer_id': 11768333, 'author': 'Spencer Mark', 'author_id': 1417500, 'author_profile': 'https://Stackoverflow.com/users/1417500', 'pm_score': 0, 'selected': False, 'text': '<p>Very interesting thing that I\'ve discovered today as I was facing the similar problem. If you use the following - it will catch the error with your custom error handler function / method:</p>\n\n<pre><code>ini_set(\'display_errors\', \'Off\');\nerror_reporting(-1);\n\nset_error_handler(array("Cmd\\Exception\\Handler", "getError"), -1 &amp; ~E_NOTICE &amp; ~E_USER_NOTICE);\n</code></pre>\n\n<p>By setting \'display_errors\' to \'Off\' you can catch still catch them with the handler.</p>\n'}, {'answer_id': 29037791, 'author': 'phoenix', 'author_id': 3023353, 'author_profile': 'https://Stackoverflow.com/users/3023353', 'pm_score': 1, 'selected': False, 'text': '<p>I\'ve been playing around with error handling for some time and it seems like it works for the most part.</p>\n\n<pre><code>function fatalHandler() {\n    global $fatalHandlerError, $fatalHandlerTitle;\n\n    $fatalHandlerError = error_get_last();\n\n    if( $fatalHandlerError !== null ) {\n\n        print($fatalHandlerTitle="{$fatalHandlerTitle} | ".join(" | ", $fatalHandlerError).\n                (preg_match("/memory/i", $fatalHandlerError["message"]) ? " | Mem: limit ".ini_get(\'memory_limit\')." / peak ".round(memory_get_peak_usage(true)/(1024*1024))."M" : "")."\\n".\n                        "GET: ".var_export($_GET,1)."\\n".\n                        "POST: ".var_export($_POST,1)."\\n".\n                        "SESSION: ".var_export($_SESSION,1)."\\n".\n                        "HEADERS: ".var_export(getallheaders(),1));\n    }\n\n    return $fatalHandlerTitle;\n}\n\nfunction fatalHandlerInit($title="phpError") {\n    global $fatalHandlerError, $fatalHandlerTitle;\n\n    $fatalHandlerTitle = $title;\n    $fatalHandlerError = error_get_last();\n\n    set_error_handler( "fatalHandler" );\n}\n</code></pre>\n\n<p>Now I have an issue where if the memory is exhausted, it doesn\'t report it every time. It seems like it depends on how much memory is being used.\nI did a script to load a large file (takes ~6.6M of memory) in an infinite loop. \nSetup1:</p>\n\n<pre><code>ini_set(\'memory_limit\', \'296M\');\n\nfatalHandlerInit("testing");\n\n$file[] = file("large file"); // copy paste a bunch of times\n</code></pre>\n\n<p>In this case I get the error to be reports and it dies on 45 file load.</p>\n\n<p>Setup2 - same but change:\nini_set(\'memory_limit\', \'299M\');</p>\n\n<p>This time I don\'t get an error and it doesn\'t even call my custom error function. The script dies on the same line.</p>\n\n<p>Does anyone have a clue why and how to go around that?</p>\n'}, {'answer_id': 72974896, 'author': 'asd', 'author_id': 19546300, 'author_profile': 'https://Stackoverflow.com/users/19546300', 'pm_score': 0, 'selected': False, 'text': "<p>At a guess, I'd say that undefined function errors travel through a different execution path than other error types. Perhaps the PHP designers could tell you more, except I doubt PHP is in any way designed.</p>\n"}]
['https://Stackoverflow.com/questions/36621', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/1615/']