ActiveMQ/Stomp debug when a message disables a consumer - php

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.

Related

Catch fatal errors in PHP in whole app by surrounding code with try/catch?

Now that we can catch fatal errors in PHP7 (set_error_handler cannot), would it be a good idea to use it to catch errors on a whole project? Mine is always going through index.php, so I was planning to do this:
try {
//All the code and includes, etc.
} catch(Error $ignored) {
//save the error in log and/or send a notification to admin.
}
I tried first to be sure:
set_error_handler(function(int $number, string $message) {
echo "Error $number: '$message'" . PHP_EOL ;
});
$var = $undeclared_var //The error is sent to the error_handler.
function_dont_exist(); //The error isn't sent to the error_handler.
try {
function_dont_exist();
}
catch(Error $E){
echo "Error"; //That works.
}
Is it a good idea / good practice to envelope the whole code with a try/catch/error to deal with them? It sounds good, but I wonder why I don't see it much. I tried and I believe it works, but it sounds too easy.
Thank you for your help!

PHP CodeIgniter Errors not stopping execution of Try Blocks

I'm using CodeIgniter and am trying to execute code in a try/catch block with the idea that errors will stop execution of the code after the error until the catch block is reached, as you would normally think it would work.
However on encountering PHP Errors, the code is continuing. This is causing a database transaction complete command to execute which is .... very bad if there's an error and all of the instructions weren't carried out properly. For example, I have this code which is executed in an ajax request:
// start transaction
$this->db->trans_start();
try {
$this->M_debug->fblog("firstName=" . $triggerOpts->{'firstXXXName'});
$data = array("test_col" => 123);
$this->db->where("id", 4);
$this->db->update("my_table", $data);
// if got this far, process is ok
$status = "process_ok";
// complete transaction
$this->db->trans_complete();
} catch (Exception $ex) {
// output the error
$this->M_debug->logError($ex);
}
In this code, I'm trying to execute a database update as part of a transaction.
My call to $this->M_debug->fblog() is designed to just log a variable to PHP Console, and I've deliberately tried to log a variable that does not exist.
This causes a PHP error, which I guess is a fatal error, and the desired result is that the code after the log commands fails, and the transaction does not complete. However after this error, despite reporting the PHP error in Chrome console, the code keeps right on executing, the database is updated and the transaction is completed. Would appreciate any help in how i could stop this from happening.
Thanks very much, G
EDIT --
As requested heres fblog(), it's simply a Chrome console log request of a variable
public function fblog( $var ) {
ChromePhp::log( $var );
}
Assuming you're using PHP 7.0 or higher, you can catch PHP errors as well as exceptions, however you need to catch Error or the parent Throwable type rather than Exception.
try {
...
} catch (Throwable $ex) {
//this will catch anything, including Errors and Exceptions
}
or catch them separately if you want to do something different for each of them...
try {
...
} catch (Exception $ex) {
//this will catch Exceptions but not errors.
} catch (Error $ex) {
//this will Errors only
}
Note that if you're still only PHP 5.x, the above won't work; you can't catch PHP errors in older PHP versions.

How to catch errors from REST service?

I am working on a PHP rest service. Many errors cause the PHP to terminate without giving any insight into the cause. Surrounding my functions in try catch clauses don't help, the script exits without entering the catch block. Is there a way to catch all/any errors in my PHP scripts?
Check your error_log. Most likely it's a PHP FATAL error that is being thrown before an Exception so it's dead before the catch statement.
To log everything, register a shutdown function in your application together with error_get_last(). For example, this will log all error that will cause your application to unexpectedly die.
function shutdown()
{
$arrError = error_get_last();
if( is_null($arrError) ) {
return true;
}
//Remove the if statement and just have the error_log() if you want to log everything
if( in_array($arrError['type'], array(E_RECOVERABLE_ERROR, E_ERROR, E_USER_ERROR)) ) { //FATAL HANDLER!
error_log("Error caught. ". $arrError['message'] ." in file ". $arrError['file'] .":". $arrError['line']);
//Then maybe do something to make this verbose in your development environment
if( ENVIRONMENT == "dev" ) {
echo "<h3>ERROR</h3> ". $arrError['message'] ." in file ". $arrError['file'] .":". $arrError['line'];
die;
}
}
}
register_shutdown_function('shutdown');

How to prevent a try-catch error from stopping execution

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 - try/catch gearman not catching timeout warning

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);
}

Categories