Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何处理客户端错误(如Guzzle或Stripe PHP客户端)_Php_Symfony_Stripe Payments - Fatal编程技术网

如何处理客户端错误(如Guzzle或Stripe PHP客户端)

如何处理客户端错误(如Guzzle或Stripe PHP客户端),php,symfony,stripe-payments,Php,Symfony,Stripe Payments,我发现自己又遇到了同样的问题:如何处理调用外部API的客户机 问题是这个 例如,如果我使用,可能会发生狂饮,它会抛出一些。同样的情况也会发生,例如,Stripe PHP客户端(这里是) 所以,问题总是一样的:对于我所做的每一个调用,我都必须捕获异常并根据它们的种类采取行动 典型示例(摘自Stripe的文档): 因此,如果我对API进行了3次调用,我必须重复此异常处理3次 我可以更好地创建像handleException(\Exception$e)这样的方法来管理异常: /** * Handle

我发现自己又遇到了同样的问题:如何处理调用外部API的客户机

问题是这个

例如,如果我使用,可能会发生狂饮,它会抛出一些。同样的情况也会发生,例如,Stripe PHP客户端(这里是)

所以,问题总是一样的:对于我所做的每一个调用,我都必须捕获异常并根据它们的种类采取行动

典型示例(摘自Stripe的文档):

因此,如果我对API进行了3次调用,我必须重复此异常处理3次

我可以更好地创建像
handleException(\Exception$e)
这样的方法来管理异常:

/**
 * Handles the Stripe's exceptions.
 *
 * @param \Exception $e
 */
private function handleException(\Exception $e)
{
    /* Since it's a decline, \Stripe\Error\Card will be caught
    $body = $e->getJsonBody();
    $err  = $body['error'];

    print('Status is:' . $e->getHttpStatus() . "\n");
    print('Type is:' . $err['type'] . "\n");
    print('Code is:' . $err['code'] . "\n");
    // param is '' in this case
    print('Param is:' . $err['param'] . "\n");
    print('Message is:' . $err['message'] . "\n");
    */

    // Authentication with Stripe's API failed
    if ($e instanceof \Stripe\Error\Authentication) {
        // Immediately re-raise this exception to make the developer aware of the problem
        throw $e;
    }
    elseif ($e instanceof \Stripe\Error\InvalidRequest) {
        // This should never happen: if we are in development mode, we raise the exception, else we simply log it
        die(dump($e));
    }
    elseif ($e instanceof \Stripe\Error\RateLimit) {
        // Too many requests made to the API too quickly
        die(dump('\Stripe\Error\Card error', $e));
    }
    elseif ($e instanceof \Stripe\Error\ApiConnection) {
        // Network communication with Stripe failed
        die(dump('\Stripe\Error\ApiConnection error', $e));
    }
    elseif ($e instanceof \Stripe\Error\Card) {
        die(dump('\Stripe\Error\Card error', $e));
    }
    elseif ($e instanceof \Stripe\Error\Base) {
        // Display a very generic error to the user, and maybe send
        // yourself an email
        die(dump('\Stripe\Error\Base error', $e));
    }
    elseif ($e instanceof \Exception) {
        // Something else happened, completely unrelated to Stripe
        die(dump('\Exception error', $e));
    }
但是,问题是:如何处理错误

分析每种异常:

  • 身份验证
    :我立即提出它,因为它一旦修复就不会再发生:开发人员只需检查访问密钥
  • InvalidRequest
    :有问题,请参阅下文
  • 费率限制
    :我应该实施某种指数退避
  • 网络通信
    :我真的不知道该怎么做,也不知道如何模拟它
  • Card
    :我现在还没有研究这个问题:我想先解决其他问题,特别是第2点和第4点
  • 因此,请参见
    elseif(\Stripe\Error\InvalidRequest)
    :如果引发此异常,我应该怎么做?在我写的评论中,如果我处于开发模式,我可以引发异常,而如果我没有,我应该记录错误。。。但是,这是解决问题的正确方法吗

    因此,确切地说,由于我不知道如何继续讨论,我如何处理这样的错误?xaples与Stripe Api一起使用,但Guzzle异常和许多其他使用异常的库也是如此

    关于如何处理这种情况,有什么指导吗?一些最佳实践?我可以从中获得灵感的一些例子?任何建议或正确的方向都将不胜感激。谢谢。

    FTW

    这是你要做的

    创建对象时,还需要创建一个中间件,然后注入它

    $handler = new CurlHandler();
    $stack   = HandlerStack::create($handler);
    $stack->push(ErrorHandlerMiddleware::create(), 'http_error');
    
    然后,您的ErrorHandlerMiddleware可以如下所示:

    class ErrorHandlerMiddleware {
        public static function create() {
            return function (callable $handler) {
                return function ($request, array $options) use ($handler {
    
                return $handler($request, $options)->then(
                    function (ResponseInterface $response) use ($request, $handler) {
                        $code = $response->getStatusCode();
                        if ($code < 400) {
                            return $response;
                        }
                        $response_body = json_decode($response->getBody(), true);
                        switch ($code) {
                            case 400:
                                // do what you need
                            case 404:
                                // do what you need
                            case 500:
                                // do what you need
                        }
                    },
                    function (RequestException $e) use ($request, $handler) {
                        throw new Exceptions\ConnectException('Service Unavailable - Connection Errors '. $e->getMessage(), $request);
                    }
                );
            };
        };
    }
    
    类ErrorHandlerMiddleware{
    公共静态函数create(){
    返回函数(可调用$handler){
    返回函数($request,array$options)使用($handler){
    返回$handler($request,$options)->然后(
    函数(ResponseInterface$response)使用($request,$handler){
    $code=$response->getStatusCode();
    如果($code<400){
    返回$response;
    }
    $response\u body=json\u decode($response->getBody(),true);
    交换机($代码){
    案例400:
    //做你需要的
    案例404:
    //做你需要的
    案例500:
    //做你需要的
    }
    },
    函数(RequestException$e)use($request,$handler){
    抛出新异常\ConnectException('服务不可用-连接错误'$e->getMessage(),$request);
    }
    );
    };
    };
    }
    
    }

    现在你不必重复你自己


    附言:当我说“做你需要的”我的意思是抛出您的自定义异常或您需要执行的任何操作

    您知道Symfony的自定义异常侦听器功能吗?至少这允许您在一个位置处理更复杂的异常。是的,好吧,但问题是我不知道捕获异常后该做什么,而不知道如何捕获它们。正如您所看到的,如果出现
    RateLmit
    异常,我必须重试呼叫,但是如果我发现了
    InvalidRequest
    异常,我该怎么办?既然InvalidRequest在生产中永远不会发生,那么是的,记录它并确保立即通知某人有问题。但我理解这些问题。我所能做的就是G看看现有的一些条带捆绑包是如何处理的。现有的条带捆绑包1)非常旧或2)根本无法处理问题3)一次集成在更大的捆绑包或某种超级所有网关中,因此它们是无用的或太多的coplex需要研究:(因此,我正在开发自己的。。。
    class ErrorHandlerMiddleware {
        public static function create() {
            return function (callable $handler) {
                return function ($request, array $options) use ($handler {
    
                return $handler($request, $options)->then(
                    function (ResponseInterface $response) use ($request, $handler) {
                        $code = $response->getStatusCode();
                        if ($code < 400) {
                            return $response;
                        }
                        $response_body = json_decode($response->getBody(), true);
                        switch ($code) {
                            case 400:
                                // do what you need
                            case 404:
                                // do what you need
                            case 500:
                                // do what you need
                        }
                    },
                    function (RequestException $e) use ($request, $handler) {
                        throw new Exceptions\ConnectException('Service Unavailable - Connection Errors '. $e->getMessage(), $request);
                    }
                );
            };
        };
    }