PHP HTTP Library and Error Handling

PHP HTTP Library and Error Handling

Recently, I was using PHP code to do some HTTP protocol request. I have the Try Catch code there. But it seems it is not working well.

I finally find a solution and fix for the bug.

First of all, I am using a object oriented framework which mostly construct by my own. I just use a lot of open source things and putting together.

I have some codes like this in WebHttpClient.php

<?php
namespace JobConsumerPHP;

require __DIR__ . '/../../vendor/autoload.php';

use \GuzzleHttp\Client;
use \GuzzleHttp\Psr7\Request;
use \GuzzleHttp\Exception\ConnectException;

class WebHttpClient
{

    private $classifierClient = null;

    private $predictionClient = null;

    private $geoServerClient = null;

    private $ioc = null;

    public function __construct($ioc)
    {
        $this->ioc = $ioc;

        $logger = $this->ioc->getService("logger");
        $config = $this->ioc->getService("config");

        $logger->info("==============WebClient config start ==============");
        $classifierURL = $config['classifierURL'];
        $classifierKey = $config['classifierKey'];

        $predictionURL = $config['predictionURL'];
        $predictionKey = $config['predictionKey'];

        $geoServerURL = $config['geoServerURL'];

        $gatewayKey = $config['gatewayKey'];
        $httpTimeout = $config['httpTimeout'];

        $logger->info("classifierURL = {$classifierURL}");
        $logger->info("classifierKey = {$classifierKey}");
        $logger->info("predictionURL = {$predictionURL}");
        $logger->info("predictionKey = {$predictionKey}");
        $logger->info("predictionKey = {$predictionKey}");
        $logger->info("httpTimeout = {$httpTimeout}");
        $logger->info("=============================================");

        try {
            // init classifier HTTP
            $this->classifierClient = new Client([
                'base_uri' => $classifierURL,
                'timeout' => $httpTimeout,
                'connect_timeout' => $httpTimeout,
                'http_errors' => false
            ]);

            // init prediction HTTP
            $this->predictionClient = new Client([
                'base_uri' => $predictionURL,
                'timeout' => $httpTimeout,
                'connect_timeout' => $httpTimeout,
                'headers' => [
                    'Content-Type' => 'application/json',
                    'x-api-key' => $predictionKey,
                    'api-gateway-key' => $gatewayKey
                ],
                'http_errors' => false
            ]);

            // init geo Server HTTP
            $this->geoServerClient = new Client([
                'base_uri' => $geoServerURL,
                'timeout' => $httpTimeout,
                'connect_timeout' => $httpTimeout,
                'http_errors' => false
            ]);
        } catch (\Exception $e) {
            $logger->error("Couldn't init the HTTP Client.");
            $logger->error($e->getMessage());
        }
    }

First of all, I have a namespace there, so I should always use \Exception, if I only put Exception there. The system can not catch the Exceptions. And the http_errors => false is also important.

If the HTTP method fail, the system need to retry that. So I have some codes like this
    /**
     * retry many times
     *
     * @param function $f
     * @param number $delay
     * @param number $retryies
     */
    public function retry($f, $delay = 10, $retryies = 3)
    {
        $logger = $this->getService("logger");

        try {
            return $f();
        } catch (\Exception $e) {
            if ($retryies > 0) {
                $logger->error("error happened " . $e->getMessage() . " system is retrying after " . $delay . " seconds" . " with the " . $retryies );
                sleep($delay);
                return $this->retry($f, $delay, $retryies - 1);
            } else {
                $logger->error($e->getMessage());
            }
        }
    }

How we use the retry function is like this>
    public function getFromClassifier($path)
    {
        return $this->ioc->retry(function () use ($path) {
            $response = $this->classifierClient->request('GET', $path , array(
                'http_errors' => false
            ));
            return $response;
        }, 10, 3);
    }

I like this solutions. And maybe, we should use an random number there, system should retry in random time, not 10 seconds always.

References:
http://stackoverflow.com/questions/32252420/guzzle-curl-error-not-catche-by-try-catch-statement-laravel
https://github.com/gidkom/php-openfire-restapi/issues/3
http://stackoverflow.com/questions/17658283/catching-exceptions-from-guzzle

猜你喜欢

转载自sillycat.iteye.com/blog/2356590