php: repeat function call 2-3 times in catch() - php

so a function crashes sometimes ( uncaught exception ) and i want to re-call it 2 times when that happens with a delay of 1 seconds let's say. Here's is the code but it doesn't seem to work:
$crashesn = 0;
function checkNum($number) {
echo $number . "<br>";
if ($number>1) {
throw new Exception("Value must be 1 or below");
}
return true;
}
try {
checkNum(2);
echo 'If you see this, the number is 1 or below';
}
catch(Exception $e) {
$crashesn++;
echo "crashes number:".$crashesn."<br>";
if ($crashesn <= 2) {
sleep(1);
checkNum(2);
} else {
echo "MESSAGE: " .$e->getMessage();
}
}
checknum is the function which throws the exception ( here it crashes every time by throwing an exception ). The problem is, when I run this piece of code, i still get on my page an error message
Fatal error: Uncaught exception 'Exception' with message 'Value must be 1 or below' in G:\fix\ta_dll\test.php:30 Stack trace: #0 c:\wwwl\test.php(45): checkNum(2) #1 {main} thrown in c:\php\test.php on line 30
instead of a "MESSAGE: ERROR DESCRIPTION". the "crashes number" line only gets printed once, not twice.
anyone knows what I am doing wrong ?

Try with a loop instead
for ($crashes = 0; $crashes < 3; $crashes++) {
try {
checkNum(2);
echo 'If you see this, the number is 1 or below';
break;
}
catch(Exception $e) {
echo "crashes number:" . $crashes . "<br>";
if ($crashes < 2) {
sleep(1);
} else {
echo "MESSAGE: " . $e->getMessage();
}
}
}
When checkNum() returns properly, the for loop is left with the break. Otherwise, when an exception is thrown, break is skipped and the loop repeats.

From your comments : it crashes sometimes (due to memory leaks i guess). So I need to auto-repeat it 2 or 3 more times when the crash happens.
Solution 1 : Try using goto ... its old school and can be evil but it might work for you
$crashesn = 0;
START:
try {
checkNum(2);
echo 'If you see this, the number is 1 or below';
break;
} catch ( Exception $e ) {
$crashesn ++;
echo "crashes number:" . $crashesn . "<br>";
if ($crashesn <= 2) {
sleep(1);
goto START;
} else {
echo "MESSAGE: " . $e->getMessage();
}
}
Solution 2: just use loop you can also read Performance of try-catch in php
$crashesn = 0;
do {
try {
checkNum(2);
echo 'If you see this, the number is 1 or below';
} catch ( Exception $e ) {
$crashesn ++;
echo "crashes number:" . $crashesn . "<br>";
if ($crashesn <= 2) {
sleep(1);
} else {
echo "MESSAGE: " . $e->getMessage();
}
}
} while ( $crashesn <= 2 );
Both would Output
2
crashes number:1
2
crashes number:2
2
crashes number:3
MESSAGE: Value must be 1 or below

In Addition to my comment: Why are you throwing an exception? Your exception is thrown, if the number is greater than 1 - remove the exception and use something like this:
function checkNum($number) {
echo $number . "<br>";
if ($number>1) {
return false;
}
return true;
}
$crashesn = 0;
$number = 2; // number from somewhere.
$failed =false;
while (!$checkNum($number)){
echo $number." is to large!";
$crashesn++;
if ($crashesn > 2){
//stop retrying it.
$failed = true;
break;
}
}
if (!$failed){
echo $number." is valid";
}else{
echo "Failed after 2 retries";
}
However it does NOT make sence to repeat the call if the number is a "fixed" value. It will fail three times or be valid on first run.
Exceptions are for cirital Erros. DON't use them to validate something you can take care of with normal logical expressions.

In your catch , u supposed to have another try catch
try {
// some code here
}
catch(Exception $e) {
try {
$crashesn++;
echo "crashes number:".$crashesn."<br>";
if ($crashesn <= 2) {
sleep(1);
checkNum(2);
}
}
catch(Exception $e) {
echo "MESSAGE: " .$e->getMessage();
}
}

$checked = false;
while ($i < 3 && $checked === false){
try{
$checked = checkNum($number);
}
catch(Exception $e){
$i++;
}
}

Related

Using try-catch in PHP how to go to finally without throw an Exception?

About the following code, how can I go to finally without throw an Exception in PHP?
try {
$db = DataSource::getConnection();
if (some condition here is TRUE) {
// go to finally without throw an exception
}
$stmt = $db->prepare($sql);
$stmt->saveMyData();
} catch (Exception $e) {
die($e->getMessage());
} finally {
$db = null;
}
Please don't do this, but here's an option:
try {
if (TRUE){
goto ugh;
}
echo "\ndid not break";
ugh:
} catch (Exception $e){
echo "\ndid catch";
} finally {
echo "\ni'm so tired";
}
I strongly encourage against using a goto. I think it's just really easy for code to get sloppy & confusing if you're using goto.
I'd recommend:
try {
if (TRUE){
echo "\nThat's better";
} else {
echo "\ndid not break";
}
} catch (Exception $e){
echo "\ndid catch";
} finally {
echo "\ni'm so tired";
}
You just wrap the rest of the try into an else in order to skip it.
Another option could be to declare a finally function, call that, and return.
//I'm declaring as a variable, as to not clutter the declared methods
//If you had one method across scripts, naming it `function doFinally(){}` could work well
$doFinally = function(){};
try {
if (TRUE){
$doFinally();
return;
}
echo "\ndid not break";
} catch (Exception $e){
echo "\ndid catch";
} finally {
$doFinally();
}
If you needed to continue the script, you could declare $doFinally something like:
$doFinally = function($reset=FALSE){
static $count;
if ($reset===TRUE){
$count = 0;
return;
} else if ($count===NULL)$count = 0;
else if ($count>0)return;
}
Then after the finally block, you could call $doFinally(TRUE) to reset it for the next try/catch

PHP MongoDB exception (Error handling)

I have a PHP platform where user write mongodb query like picture below
and following code print result as a table
$m = new MongoClient();
$db = $m->Forensic;
$coll= $db->mobile_data;
if (isset($_POST['txt_area']) && !empty($_POST['txt_area'])) {
$d = ($_POST['txt_area']);
$p = json_decode($d);
$user_code = $coll->find($p);
When I type correct code system able to ouput all my result but if I write query wrong I am getting error message like
Warning: MongoCollection::find(): expects parameter 1 to be an array or object, null given in C:\xampp\htdocs\reports5.php on line 126
to catch that error i have tried following try catch code but no luck
try {
if (isset($_POST['txt_area']) && !empty($_POST['txt_area'])) {
$d = ($_POST['txt_area']);
$p = json_decode($d);
$user_code = $coll->find($p);
$NumberOfRow2 = $user_code->count();
$user_code->sort(array('Chat_group' => -1, 'Instant_Message' => 1 ));
}
}
catch (MongoCursorException $e) {
echo "error message: ".$e->getMessage()."\n";
echo "error code: ".$e->getCode()."\n";
}
catch (MongoException $e)
{
echo $e->getMessage();
}
catch(MongoResultException $e) {
echo $e->getMessage(), "\n";
$res = $e->getDocument();
var_dump($res);
}
what would be the best way to catch above error
The warning you're seeing is PHP complaining that $coll->find($p); expects $p to be either array or object while it's null. Quoting json_decode documentation:
NULL is returned if the json cannot be decoded or if the encoded data is deeper than the recursion limit.
So a proper way to defend against warning would be:
$p = json_decode($d);
if ($p === null) {
echo "Provided query is invalid!";
} else {
// do your logic
}

Fatal error: Uncaught no such id - API response(PHP)

I am trying to get all infos from an API, where I dont know every single ID the API can get me. So basically I am calling for 1 info after another while I increase the ID:
<?php
$i = 0;
while ($i < 1000)
{
if ($api->traits()->get($i) == "Uncaught no such id")
{
echo "do something";
$i++;
}
else
{
echo "do something else";
$i++;
}
}
My error code:
Fatal error: Uncaught no such id (status: 404; url:....)
Is there a way that the program doesn't stop on a Fatal error? Or that it reboot the script on fatal error with one higher ID?
I believe you're seeing an Uncaught Exception. See the catch block? That's what it means by "uncaught".
Try this:
<?php
$i = 0;
while ($i < 1000)
{
try
{
$trait = $api->traits()->get($i);
}
catch (Exception $ex)
{
echo "Error: " . $ex->getMessage();
echo "(do something else)";
$i++;
continue;
}
echo "found trait " . $trait;
$i++;
}
Also, this is probably a situation where you should use a for loop instead of a while loop.
<?php
for ($i = 0; $i < 1000; $i++)
{
try
{
$trait = $api->traits()->get($i);
}
catch (Exception $ex)
{
echo "Error: " . $ex->getMessage();
echo "(do something else)";
continue;
}
echo "found trait " . $trait;
}
I should also add that Exception is the very base type or class of exception, and APIs and libraries will typically throw a more specific type of exception.
catch (Exception $ex) { ... }
will catch any type of exception, but
catch (HttpConnectionException $ex) { ... }
would only catch an Exception of type HttpConnectionException. This allows you to handle specific types of errors differently. You can use get_class($ex) to see what exact type of Exception the API is throwing if you like.

try catch exception?

I have some script, that calls an error: Fatal error: Call to a member function GetData() on a non-object in .... I'm trying to catch this error, but it doesn't work, watch my code below:
try {
if ($data = $m->users()->GetData()) {
print_r( $data );
}
}
catch (Exception $e) {
echo 'Hey, it is an error man!';
}
How to catch it? Turning off all errors in php is impossible. I mean that sometimes I really need this error.
upd 1. Well, solution is simple:
if (is_object($m->users()) && ($data = $m->users()->GetData())) {
print_r( $data );
} else {
echo 'Hey, it is an error man!';
Thank you all!
In PHP errors and exceptions are from different separated worlds. Look more
PHP: exceptions vs errors?
You can check returned object before call method GetData()
try {
if (is_object($m->users()) && ($data = $m->users()->GetData())) {
print_r( $data );
}
} catch (Exception $e) {
echo 'Hey, it's an error man!';
}
use following to avoid your error and you should used shutdown error handler.
try {
$obj = $m->users();
if ($data =$obj->GetData()) {
print_r( $data );
}
}
catch (Exception $e) {
echo 'Hey, it's an error man!';
}
//shut down error handler
function shutdownErrorHandler() {
$error = error_get_last();
if ($error !== NULL) {
echo "Error: [SHUTDOWN] error type: " . $error['type'] . " | error file: " . $error['file'] . " | line: " . $error['line'] . " | error message: " . $error['message'] . PHP_EOL;
} else {
echo "Normal shutdown or user aborted";
}
}
register_shutdown_function('shutdownErrorHandler');
Fatal Errors are not the same as Exceptions, and they are not usually recoverable. What they are, however, is usually avoidable, and sometimes they are "catchable" via PHP5's set_error_handler function.
Best practice, however, is to simply do the work of checking for valid objects before trying to call methods on them.

How to handle exception with PhpExcel?

I'm using PhpExcel for my app and see a error. I've tried handling exception with
try{}catch(){} but it doesn't work. How to handle exception with PhpExcel? Here is my code:
function import($excelObj) {
$sheet=$excelObj->getActiveSheet();
$cell = $sheet->getCellByColumnAndRow(1, 10);//assume we need calculate at col 1, row 10
try {
//This line seen error, but cannot echo in catch.
$val = $cell->getCalculatedValue(); // $cell contain a formula, example: `=A1+A6-A8`
// with A1 is constant, A6 is formula `=A2*A5`
// and A8 is another `=A1/(A4*100)-A7`
return $val;
} catch (Exception $e) {
echo $e->getTraceAsTring();
}
}
Thank for helps!
The calculation engine should throw a normal PHP exception that is catcheable. The front-end logic that I use for debugging calculation engine errors is:
// enable debugging
PHPExcel_Calculation::getInstance()->writeDebugLog = true;
$formulaValue = $sheet->getCell($cell)->getValue();
echo '<b>'.$cell.' Value is </b>'.$formulaValue."<br />\n";
$calculate = false;
try {
$tokens = PHPExcel_Calculation::getInstance()->parseFormula($formulaValue,$sheet->getCell($cell));
echo '<b>Parser Stack :-</b><pre>';
print_r($tokens);
echo '</pre>';
$calculate = true;
} catch (Exception $e) {
echo "PARSER ERROR: ".$e->getMessage()."<br />\n";
echo '<b>Parser Stack :-</b><pre>';
print_r($tokens);
echo '</pre>';
}
if ($calculate) {
// calculate
try {
$cellValue = $sheet->getCell($cell)->getCalculatedValue();
} catch (Exception $e) {
echo "CALCULATION ENGINE ERROR: ".$e->getMessage()."<br />\n";
echo '<h3>Evaluation Log:</h3><pre>';
print_r(PHPExcel_Calculation::getInstance()->debugLog);
echo '</pre>';
}
}
This gives a lot of additional information about how the calculation engine works, that can be extremely useful when debugging.

Categories