如何在PHP中捕获条带致命错误?

glo*_*idt 4 php error-handling stripe-payments

我正在使用Stripe.js元素来构建应用程序。使用Stripe提供的测试卡号,我没有问题。所有工作均按预期进行。

我现在专注于错误处理。当使用测试卡4000 0000 0000 0002处理故意被拒绝的卡时,出现此错误:

致命错误:未捕获的Stripe \ Error \ Card:您的卡被拒绝。在C:\ Apache24 \ htdocs ... \ vendor \ stripe \ stripe-php \ lib \ ApiRequestor.php:128中,来自API请求{token}。...

现在,我假设这不是PHP致命错误(无法在try / catch块中处理),因此我搜索并找到了此示例并将其实现到我的代码中,如下所示:

\Stripe\Stripe::setApiKey(self::APIKEY);

    $charge_arr = array(
        "key" => value, etc ... )

        try {               
            $charge = \Stripe\Charge::create($charge_arr);
            if($charge->paid == true) { 
                echo '<br>the card was successfully charged!';
            }

        } catch (\Stripe\Error\Base $e) {
            echo '<br>base';
            echo ($e->getMessage());

        } catch (\Stripe\Error\Card $e) {
            $body = $e->getJsonBody();
            $err  = $body['error'];

            print('Status is:' . $e->getHttpStatus() . "\n");
            print('Type is:' . $err['type'] . "\n");
            print('Code is:' . $err['code'] . "\n");                

            echo ($e->getMessage()); 

        } catch (\Stripe\Error\Authentication $e) {
            echo '<br>Auth';                
            // a good one to catch
        } catch (\Stripe\Error\InvalidRequest $e) {
            echo '<br>Invalid Request';             
            // and catch this one just in case
        } catch (Exception $e) {
            //catch any non-stripe exceptions
        }
Run Code Online (Sandbox Code Playgroud)

但是,这不会捕获该错误。该消息继续显示,就像我遇到catch块之前一样。

有任何提示为什么我会出现致命错误?我当然希望卡被拒绝,但我希望可以在try / catch块中处理卡被拒绝的结果。

编辑

我应该补充一点,我正在使用composer包含Stripe php库。

进一步说明:可能不相关,但是对于所有应该被拒绝的测试卡,都会出现致命错误消息。每张卡的错误消息中均清楚说明了拒绝的原因,例如(逐字)邮政编码未通过验证,CVC不正确,卡已过期等。

正如@Ywain正确指出的那样,这实际上不是try / catch块问题。致命错误首先是由计费交易生成的。换句话说,对\ Stripe \ Charge的调用应返回带有适当标志或字段值的JSON数组,而不是致命错误。

Sym*_*mby 5

Stripe在事务过程中可能会引发许多异常。他们的API具有出色的示例代码,可提供捕获Stripe API可能引发的各种异常的模板。

try {
  // Use Stripe's library to make requests...
} catch(\Stripe\Error\Card $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");
} catch (\Stripe\Error\RateLimit $e) {
  // Too many requests made to the API too quickly
} catch (\Stripe\Error\InvalidRequest $e) {
  // Invalid parameters were supplied to Stripe's API
} catch (\Stripe\Error\Authentication $e) {
  // Authentication with Stripe's API failed
  // (maybe you changed API keys recently)
} catch (\Stripe\Error\ApiConnection $e) {
  // Network communication with Stripe failed
} catch (\Stripe\Error\Base $e) {
  // Display a very generic error to the user, and maybe send
  // yourself an email
} catch (Exception $e) {
  // Something else happened, completely unrelated to Stripe
}
Run Code Online (Sandbox Code Playgroud)

还要记住,一旦捕获到异常,除非您进行特定的操作以结束脚本或更改执行路径,否则脚本将继续幸福地运行其余代码,而不会引发任何异常。考虑这个过于简单的示例。

try {
    $charge = \Stripe\Charge::create($charge_arr);
} catch (\Stripe\Error\Card $e) {
    echo("I had an error!");
}
echo ("I completed Successfully");
Run Code Online (Sandbox Code Playgroud)

卡被拒绝,并且api抛出\ Stripe \ Error \ Card。然后,您收到以下输出。

我出错了!我成功完成了

如果执行路径中有多个API调用,则这很重要。您很可能会捕获引发的异常,只是在以后的调用中又抛出了一个您不希望运行的异常。您应该对API进行所有调用,这些调用都可能引发包裹在try / catch中的异常。如果您期望从较早的调用中捕获到错误以阻止其他代码执行,则还需要注意您的执行路径。过于简单的例子。

try {
    $charge = \Stripe\Charge::create($charge_arr);
    $declined = false;
} catch (\Stripe\Error\Card $e) {
    echo("I had an error!");
    $declined = true;
}
if(!$declined) {
    echo ("I completed Successfully");
}
Run Code Online (Sandbox Code Playgroud)


小智 1

我认为你需要捕捉不同类型的抛出错误。

\Stripe\Stripe::setApiKey(self::APIKEY);

    $charge_arr = array(
        "key" => value, etc ... )

    try {

        $charge = \Stripe\Charge::create($charge_arr);

    } catch (\Stripe\Error\Base $e) {       
        echo ($e->getMessage());
    } catch (\Stripe\Error\Card $e) {
        echo ($e->getMessage()); // I think this is the missing one
    } catch (\Stripe\Error\Authentication $e) {
        // a good one to catch
    } catch (\Stripe\Error\InvalidRequest $e) {
        // and catch this one just in case
    } catch (Exception $e) {
        //catch any non-stripe exceptions
    }
Run Code Online (Sandbox Code Playgroud)