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