I'm using the php gearman client and I'm trying to catch/ignore any errors in the event the gearman server is offline:
try {
$gearman = new GearmanClient();
$gearman->addServer('apps-1');
$gearman->setTimeout(4000);
$result = $gearman->doNormal("function", "params");
} catch (Exception $e) {}
However, this is still outputting the following error message:
Warning: GearmanClient::doNormal(): _client_do(GEARMAN_TIMEOUT) occured during gearman_client_run_tasks() -> libgearman/client.cc:154
I know the error message is just a warning not a fatal error but I was hoping the try/catch would suppress it. Anyone know of a way around this? Putting an # symbol just before $gearman->doNormal() does suppress the error however I don't know if thats the politically correct way of doing it.
Can someone help me out?
That is due to implementation. In PHP errors do not raise exceptions. If you want your program to be notified when a timeout occurs you have to manually inject into the errorhandler using set_error_handler.
$errorHandler = set_error_handler(
function($errorNumer, $errorString) {
//possibly handle error here
}
);
$gearman = new GearmanClient();
$gearman->addServer('apps-1');
$gearman->setTimeout(4000);
$result = $gearman->doNormal("function", "params");
if (isset($errorHandler)) {
set_error_handle($errorHandler);
}
Related
PHP is famous for displaying ugly error messages, though they are useful at times. I know I can hide error messages with
error_reporting(0);
That's fine, but it leaves the user completely in the dark as to what is going on. The page has stopped working and they don't know why. How can I display a simple message along the lines of "Sorry, there is an error. Please send an e-mail to the webmaster"?
It would be the same message for all errors, and I'm thinking of maybe popping up a javascript alert, but open to any other ideas.
Implement an error and exception handler
You need to write a custom error handler like this. As you can see at the bottom, I am introducing a FATAL error. Here PHP does not spit any ugly error messages as you have quoted. It would just print Some Error Occured. Please Try Later.
<?php
set_error_handler( "log_error" );
set_exception_handler( "log_exception" );
function log_error( $num, $str, $file, $line, $context = null )
{
log_exception( new ErrorException( $str, 0, $num, $file, $line ) );
}
function log_exception( Exception $e )
{
http_response_code(500);
log_error($e);
echo "Some Error Occured. Please Try Later.";
exit();
}
error_reporting(E_ALL);
require_once("texsss.php");// I am doing a FATAL Error here
There are some rules that should apply to production servers:
Never show them the original PHP error message! Set display_errors = off.
Log those errors. Set log_errors = on and define a valid log target in error_log.
Monitor the error log, and act upon it. :)
The handling of errors to the user side has been sufficiently answered by the others.
You can write custom error handler that does it
http://php.net/manual/en/function.set-error-handler.php
This is typically done via Exceptions. If something goes awry, you'd throw an Exception and then "handle it" with an exception handler.
function exception_handler($exception) {
echo "Oops! Something went wrong! We're looking into it!";
}
set_exception_handler('exception_handler');
throw new Exception('Uncaught Exception');
You can also catch a number of fatal errors by using register_shutdown_function.
set_error_handler might also tickle your fancy.
User custom error handling set_error_handler
and exception handler set_exception_handler
and there you can do what ever you like.
I've read this thread: php: catch exception and continue execution, is it possible?
Every answer suggests that a try catch will continue executing the script. Here is an example where it doesn't:
try{ $load = #sys_getloadavg(); }
catch (Exception $e){ echo 'Couldn\'t find load average.<br>'; return false; }
I'm running it on xampp on windows, which could be why it errors (it gives a Call to undefined function sys_getloadavg() error when the # is removed), but that isn't the issue in question. It could be any function that doesn't exist, isn't supported or fails - I can not get the script to continue executing.
Another example is if there is a syntax error in the try, say I'm including an external file and parsing it as an array. This also produces an error and stops executing.
Is there any brute force way to continue the script running, regardless of what fails in the try?
Unlike other languages, there's a difference in PHP between exceptions and errors. This would be like a compile error in other languages. that require declaration files. You can't catch or ignore Fatal errors like a function not exisiting. You can test for existence before using though:
if( function_exists('sys_getloadavg') {
try{ $load = #sys_getloadavg(); }
catch (Exception $e){ echo 'Couldn\'t find load average.<br>'; return false; }
}
PHP is famous for displaying ugly error messages, though they are useful at times. I know I can hide error messages with
error_reporting(0);
That's fine, but it leaves the user completely in the dark as to what is going on. The page has stopped working and they don't know why. How can I display a simple message along the lines of "Sorry, there is an error. Please send an e-mail to the webmaster"?
It would be the same message for all errors, and I'm thinking of maybe popping up a javascript alert, but open to any other ideas.
Implement an error and exception handler
You need to write a custom error handler like this. As you can see at the bottom, I am introducing a FATAL error. Here PHP does not spit any ugly error messages as you have quoted. It would just print Some Error Occured. Please Try Later.
<?php
set_error_handler( "log_error" );
set_exception_handler( "log_exception" );
function log_error( $num, $str, $file, $line, $context = null )
{
log_exception( new ErrorException( $str, 0, $num, $file, $line ) );
}
function log_exception( Exception $e )
{
http_response_code(500);
log_error($e);
echo "Some Error Occured. Please Try Later.";
exit();
}
error_reporting(E_ALL);
require_once("texsss.php");// I am doing a FATAL Error here
There are some rules that should apply to production servers:
Never show them the original PHP error message! Set display_errors = off.
Log those errors. Set log_errors = on and define a valid log target in error_log.
Monitor the error log, and act upon it. :)
The handling of errors to the user side has been sufficiently answered by the others.
You can write custom error handler that does it
http://php.net/manual/en/function.set-error-handler.php
This is typically done via Exceptions. If something goes awry, you'd throw an Exception and then "handle it" with an exception handler.
function exception_handler($exception) {
echo "Oops! Something went wrong! We're looking into it!";
}
set_exception_handler('exception_handler');
throw new Exception('Uncaught Exception');
You can also catch a number of fatal errors by using register_shutdown_function.
set_error_handler might also tickle your fancy.
User custom error handling set_error_handler
and exception handler set_exception_handler
and there you can do what ever you like.
Why am I getting this error?
Warning: file_get_contents(http://www.example.com) [function.file-get-contents]: failed to open stream: HTTP request failed! in C:\xampp\htdocs\test.php on line 22
Fatal error: Maximum execution time of 30 seconds exceeded in C:\xampp\htdocs\test.php on line 22
Here is the code:
try {
$sgs = file_get_contents("http://www.example.com");
}
catch (Exception $e) {
echo '123';
}
echo '467';
Aren't try\catch supposed to continue the excecution of the code? Or maybe there is some different way to do it?
try... catch is more for null object exceptions and manually thrown exceptions. It really isn't the same paradigm as you might see in Java. Warnings are almost deceptive in the fact that they will specifically ignore try...catch blocks.
To suppress a warning, prefix the method call (or array access) with an #.
$a = array();
$b = #$a[ 1 ]; // array key does not exist, but there is no error.
$foo = #file_get_contents( "http://somewhere.com" );
if( FALSE === $foo ){
// you may want to read on === there;s a lot to cover here.
// read has failed.
}
Oh, and it is best to view Fatal Exceptions are also completely uncatchable. Some of them can be caught in some circumstances, but really, you want to fix fatal errors, you don't want to handle them.
catch cannot catch a fatal error.
Just search for timeout in the manual for file_get_contents, there are several solutions listed there, here is one:
$ctx = stream_context_create(array(
'http' => array(
'timeout' => 1
)
)
);
file_get_contents("http://example.com/", 0, $ctx);
try..catch will only catch exceptions. A fatal error is not an exception.
If PHP exceeds its maximum execution time, there's nothing you can do. PHP simply stops dead. It's the same if PHP runs out of memory: Nothing you can do to fix it after it's happened.
In other words, exceptions are errors you can potentially recover from. Fatal errors are, well, fatal and unrecoverable.
In PHP a fatal error will halt execution of the script. There are ways to do something when you run into them, but the idea of a fatal error is that it should not be caught.
Here are some good details: http://pc-technic.blogspot.com/2010/10/php-filegetcontents-exception-handling.html
Basically change your code to do the following:
try {
#$sgs = file_get_contents("http://www.example.com");
if ($sgs == FALSE)
{
// throw the exception or just deal with it
}
} catch (Exception $e) {
echo '123';
}
echo '467';
Note the use of the '#' symbol. This tells PHP to ignore errors raised by that particular piece of code. Exception handling in PHP is very different than java/c# due to the "after the fact" nature of it.
Fatal errors in PHP are not caught. Error handling and Exception handling are two different things. However if you are hell bent on handling fatal errors as exception, you will need to set up your own error handler and direct all errors to it, make your error handler throw exceptions and you can then catch them.
file_get_contents doesn't throw exception (and thus errors and warnings it throws aren't catchable). You are getting PHP warning and then fatal error, which explains you why the script doesn't continue - it exceeded limit for loading scripts set in php.ini.
I am scratching my head trying to debug a PHP transaction that seems to error out one of my consumers. I can detect if my consumer is running by GREPping the process list, before I insert a new message, but no way of knowing what was in there before and what caused the fatal error.
My PHP consumer is roughly:
while($isRunning == true) {
try{
if($frame = $this->stomp->readFrame()) {
$body = $frame->body;
$this->stomp->ack($frame);
}
} catch(StompException $e) {
$msg = 'Stomp Monitor readFrame() Callback Fail: '.$e->getMessage();
error_log($msg);
}
}
Is there any way to catch fatal errors or anything that will break it out of the infinite loop?
Thanks,
Steve
Try setting a top level exception handler
Perhaps there is an exception that your not catching. Catch it and log it so you know why the process dies.