php - try, catch, and retry

后端 未结 6 2106
一向
一向 2020-12-23 19:49

Sometimes my code breaks and it is out of my control

How would I do the following?

try {
//do my stuff
}
catch {
//sleep and try again
}


        
相关标签:
6条回答
  • 2020-12-23 20:20

    Here is an easy algorithm:

        do{
            try {
                $tryAgain = false;
                /* Do everything that throws error here */
    
            }
            catch(Exception $e) {
                $tryAgain = true;
                /* Do error reporting/archiving/logs here */
    
            }
        } while($tryAgain);
    
    0 讨论(0)
  • 2020-12-23 20:23

    To be able to catch an exception you have to first throw one. Something like this.

    <?php
    function inverse($x) {
        if (!$x) {
            throw new Exception('Division by zero.');
        }
        return 1/$x;
    }
    
    try {
        echo inverse(5) . "\n";
        echo inverse(0) . "\n";
    } catch (Exception $e) {
        echo 'Caught exception: ',  $e->getMessage(), "\n";
    }
    
    // Continue execution
    echo "Hello World\n";
    ?>
    

    There are certain built in exceptions : http://php.net/manual/en/spl.exceptions.php

    0 讨论(0)
  • 2020-12-23 20:30

    You can try something like this:

    function exception_error_handler($errno, $errstr, $errfile, $errline ) {
        throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
    }
    set_error_handler("exception_error_handler");
    
    $NUM_OF_ATTEMPTS = 5;
    $attempts = 0;
    
    do {
    
        try
        {
            executeCode();
        } catch (Exception $e) {
            $attempts++;
            sleep(1);
            continue;
        }
    
        break;
    
    } while($attempts < $NUM_OF_ATTEMPTS);
    
    function executeCode(){
        echo "Hello world!";
    }
    

    Here, we perform a do...while loop so that the code is executed at least once. If the executeCode() function experiences an error, it will throw an Exception which the try...catch block will capture. The catch block will then increment the variable $attempt by one and call continue to test the while condition for the next iteration. If there have already been five attempts, the loop will exit and the script can continue. If there is no error, i.e. the continue statement from the catch block is not executed, the loop will break, thus finishing the script.

    Note the use of the set_error_handler function taken from here. We do this so that all errors within the executeCode() function are caught, even if we don't manually throw the errors ourselves.

    If you believe your code may fail numerous times, the sleep() function may be beneficial before the continue statement. 'Slowing' down the possibly infinite loop will help with lower your CPU Usage.

    It is not a good idea to have a script run infinitely until it is successful, since an error that is present in the first 100 iterations of a loop, is unlikely to ever be resolved, thus causing the script to 'freeze' up. More oft than not, it is better to re-evaluate the code that you would like run multiple times in the case of an error, and improve it to properly handle any errors that come its way.

    0 讨论(0)
  • 2020-12-23 20:32

    Simply :

    function doSomething($params, $try = 1){
        try{
            //do something
            return true;
        }
        catch(Exception $e){
            if($try <5){
                 sleep(10);
                 //optionnaly log or send notice mail with $e and $try
                 doSomething($params, $try++);
            }
            else{ 
                 return false;
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-23 20:33

    I don't entirely understand why you would want to, as there is a good chance you will create an infinite loop. However, if the code is likely to succeed after a small sleep, for whatever reason, below is a solution

    while(true){
        // execute the code you are attempting
        if(some condition to signal success){
            break; // exit the loop
        }
    
        sleep(2); // 2 seconds
    }
    
    0 讨论(0)
  • 2020-12-23 20:35

    This library seems cool, it has different backoff strategies you can choose from and keeps you from implementing the retry logic every time.

    https://github.com/stechstudio/backoff

    A sample code:

    $result = backoff(function() {
        return doSomeWorkThatMightFail();
    });
    
    0 讨论(0)
提交回复
热议问题