I'm handling some PHP errors during an Ajax call and I get the following message in Chrome Console:
An uncaught Exception was encountered
Type: Error
Message: Call to undefined function data()
Filename: /var/www/application/models/M_ajax.php
Line Number: 604
Backtrace:
File: /var/www/application/controllers/Global_fxns.php
Line: 47
Function: _4___signIn
File: /var/www/html/index.php
Line: 349
Function: require_once
The thing is, its inside a try/catch block. And PHP errors should be caught. For example, if i execute this code inside the try block
strlen();
The code is caught as you would expect, as strlen expects a parameter. But this error is not caught. The line of code that is triggering the error is
if ( ! $this->M_account->addUserTrafficEvent( $userId, data('Y-m-d >H:i:s'), 2.1, '' ) ) {
And it's an error because I meant to type 'date' instead of 'data' to use PHP's date function, and because 'data' is not a function its creating an error. Why isn't this error being caught? Is there some kind of difference between errors created with PHP functions and user-defined functions, and if so shouldn't it still be caught? It's generating a PHP error message after-all
Thanks
From PHP 7 you can use catch(Error $err).
<?php
try {
data('Y-m-d >H:i:s');
} catch (Exception $exc) {
echo 'Fatal exception caught: '.$exc->getMessage();
} catch (Error $err) {
echo 'Fatal error caught: '.$err->getMessage();
}
?>
Checkout the Fiddle I've made for you
Related
When attempting to use the Asana API PHP library from here https://github.com/Asana/php-asana I get the following error:
Fatal error: Class 'Error' not found in \src\Asana\Dispatcher\OAuthDispatcher.php on line 49
I realise the error is because the authorization is not working - but how can I fix it to actually throw an exception?
you need to figure out if the class Error is exists and in a loader path.
but for now you can wrap problematic code to try.... catch
try{
line 49 code here
}catch(Exception $e){}
The entry point (front controller) for our software is wrapped in a try catch block which catches exceptions and then includes a PHP file to show a friendly error page, as well as emailing us about the exception. This work perfectly, however it misses PHP fatal errors which just show a HTTP 500 response. I'm trying to catch those errors in the same way as exceptions.
At the moment, we have this in the application's entry point:
try {
// Register a shutdown handler for fatal errors
register_shutdown_function(function() {
$error = error_get_last();
// Did this request throw an error that wasn't handled?
if ($error !== null) {
throw new Exception('PHP fatal error!');
}
});
// ...normal front controller stuff
} catch (Exception $e) {
// show fancy error screen with debug information
include 'themes/error/500.php';
}
Here, I'm throwing an exception when PHP throws a fatal error in the hopes that it gets handled by the normal exception handling procedure. However, the exception never gets caught:
Fatal error: Uncaught exception 'Exception' with message 'PHP fatal error!'
How can I achieve what I want to do here?
You should not use register_shutdown_function() for that - it makes no sense since you're already at stage when script is exiting. PHP allow you to handle errors via set_error_handler() function.
But note, you can not handle fatal errors with that (such as calling undefined functions) - and, of cause, parse error as well:
The following error types cannot 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.
I have a script that scrapes some old HTML. It does about 1000 pages a day, and every so often it chokes for some reason and throws up the following error:
PHP Catchable fatal error: Argument 1 passed to DOMXPath::__construct() must be an instance of DOMDocument, null given, called in /var/scraper/autotrader/inc/QueryPath/QueryPath/CSS/DOMTraverser.php on line 417 and defined in /var/scraper/autotrader/inc/QueryPath/QueryPath/CSS/DOMTraverser.php on line 467
At first I thought it was the error was generated when htmlqp($html) was called, but I have wrapped it in a try{} statement and it didnt catch anything:
UPDATE:
I've found the offending line of code by using # to see when the script would terminate without error. It's this line:
try {
$items = $html->find('.searchResultHeader')->find('.vehTitle'); //this one
} catch (Exception $e) {
var_dump(get_class($e));
echo 'big dump'.$e->getTraceAsString();
}
When it bombs out, it doesn't even echo 'big dump', so it really doesn't seem to be catching it.
I'm wondering if this is maybe a fault with QueryPath's error handling rather than my own?
This:
$html->find('.searchResultHeader')->find('.vehTitle');
is the same as this:
$html->find('.searchResultHeader .vehTitle');
But without the risk of calling null->find();
If you really want to do it in 2 steps, use an if, not a try:
if($el = $html->find('.searchResultHeader')) $items = $el->find('.vehTitle');
Or maybe a ternary:
$items = ($el = $html->find('.searchResultHeader')) ? $el->find('.vehTitle') : null;
It is not catching because a standard try catch block will not catch errors of this type. In order to catch a 'Catchable' fatal error a Set Error Handler for the E_RECOVERABLE_ERROR is needed.
See Also: How can I catch a “catchable fatal error” on PHP type hinting?.
I'm playing around with exceptions in PHP. For example, I have a script that reads a $_GET request and loads a file; If the file doesn't exists, an new exception should be thrown:
if ( file_exists( $_SERVER['DOCUMENT_ROOT'] .'/'.$_GET['image'] ) ) {
// Something real amazing happens here.
}
else {
throw new Exception("The requested file does not exists.");
}
The problem is that, when I try to supply an non existent file for the test, I got a 500 error instead of the exception message. The server log is the following:
[09-Jul-2013 18:26:16 UTC] PHP Fatal error: Uncaught exception 'Exception' with message 'The requested file does not exists.' in C:\sites\wonderfulproject\script.php:40
Stack trace:
#0 {main}
thrown in C:\sites\wonderfulproject\script.php on line 40
I wonder if I'm missing something real obvious here.
I've checked this question PHP fatal error: Uncaught exception 'Exception' with message but it's not quite like my issue, and have no concise answer.
Help, please?
* EDIT *
It seems this is something related to the throw keyword. If I use echo for example, I got the message printed on the screen, like this:
exception 'Exception' with message 'The file does not exists.' in C:\sites\wonderfulproject\script.php:183 Stack trace: #0 {main}
Why is that?
** EDIT 2 **
Thanks to #Orangepill, I got a better understanding about how to handle exceptions. And I found a superb tut from nettuts that helped a lot. The link: http://net.tutsplus.com/tutorials/php/the-ins-and-outs-of-php-exceptions/
This is expected behavior for an uncaught exception with display_errors off.
Your options here are to turn on display_errors via php or in the ini file or catch and output the exception.
ini_set("display_errors", 1);
or
try{
// code that may throw an exception
} catch(Exception $e){
echo $e->getMessage();
}
If you are throwing exceptions, the intention is that somewhere further down the line something will catch and deal with it. If not it is a server error (500).
Another option for you would be to use set_exception_handler to set a default error handler for your script.
function default_exception_handler(Exception $e){
// show something to the user letting them know we fell down
echo "<h2>Something Bad Happened</h2>";
echo "<p>We fill find the person responsible and have them shot</p>";
// do some logging for the exception and call the kill_programmer function.
}
set_exception_handler("default_exception_handler");
Just adding a bit of extra information here in case someone has the same issue as me.
I use namespaces in my code and I had a class with a function that throws an Exception.
However my try/catch code in another class file was completely ignored and the normal PHP error for an uncatched exception was thrown.
Turned out I forgot to add "use \Exception;" at the top, adding that solved the error.
For
throw new Exception('test exception');
I got 500 (but didn't see anything in the browser), until I put
php_flag display_errors on
in my .htaccess (just for a subfolder).
There are also more detailed settings,
see Enabling error display in php via htaccess only
Here is the part of my code:
// ... code ...
$action = self::defineAction( $request->getPath() );
try {
$response = Controller::$action( $request );
} catch( \BadMethodCallException $exception ) {
Logger::logError( $exception );
$response = new NotFoundResponse();
}
// ... code ...
I try to catch an exception if by some accident the action of the controller with the defined name is not implemented or if the name is defined wrongly.
But instead of catching exception I get Fatal Error in Apache's error log:
PHP Fatal error: Call to undefined method app\\Controller::testingAction() ...
If I try to call an undefined method inside the existing (defined and callable) action of the controller, I also can't catch the aforementioned exception - the Fatal Error occurs instead:
PHP Fatal error: Call to undefined method app\\SomeClass::someUndefinedMethod() in /********/Controller.php on line *** ...
Replacing the "\BadMethodCallException" by the "\Exception" has no effect: I'm keeping get the Fatal Errors.
Putting the "try-catch" block inside the every action of the controller is not the acceptable solution for me.
Why the exception can't be caught this way? How can I solve this problem?
I'm running PHP 5.3.8.
Catch blocks can only catch thrown exceptions, not errors. Call to undefined method is an error and you will need to test for this and throw an exception yourself. Please see this for differences between exceptions and errors.
You can test whether a method exists by doing something like this:
if( !method_exists('app\Controller', 'testingAction') ) {
throw new \BadMethodCallException();
}