【问题标题】:Abstracting try/catch PHP - stripe error handling抽象 try/catch PHP - 条带错误处理
【发布时间】:2017-12-10 07:28:25
【问题描述】:

我正在处理来自 Stripe API 的错误 - 使用 Stripe 文档中提供的标准 try/catch 块一切正常:

try {

  // Use Stripe's library to make requests...

} catch(\Stripe\Error\Card $e) {

  //card errors

  $body = $e->getJsonBody();
  $err  = $body['error'];

  print('Status is:' . $e->getHttpStatus() . "\n");
  print('Type is:' . $err['type'] . "\n");
  print('Code is:' . $err['code'] . "\n");
  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
}

但是,这是很多代码,我发现自己在重复它。我对如何整理它有点困惑。像这样的东西是理想的:

try {

  // Use Stripe's library to make requests...

} // catch all errors in one line

【问题讨论】:

    标签: php error-handling try-catch stripe-payments abstraction


    【解决方案1】:

    有一个为你处理它的函数:

    function makeStripeApiCall($method, $args) {
        try {
            // call method
        } catch (...) {
            // handle error type 1
        } catch (...) {
            // handle error type 2
        } ...
    }
    

    现在:

    1. 如何传递$method?有几种方法可以做到这一点;例如:

      $method = 'charge';
      $this->stripe->{$method}($args);
      
      $method = [$stripe, 'charge'];
      call_user_func_array($method, $args);
      

      $method = function () use ($stripe, $args) { return $stripe->charge($args); };
      $method();
      

      选择最适合您的情况。

    2. 如何准确处理错误?

      您应该捕获特定的 Stripe 异常并将它们适当地转换为您自己的内部异常类型。您希望以不同的方式处理几种广泛类型的问题:

      1. 错误请求,例如卡被拒绝:你想直接在调用业务逻辑代码中捕获这些错误,并根据具体问题做一些事情

      2. 服务中断,例如Stripe\Error\ApiConnection 或速率限制:除了稍后再试之外,您无法对它们做太多事情,您会希望在更高的地方捕获这些错误并向用户显示“抱歉,稍后再试”消息

      3. 错误的配置,例如Stripe\Error\Authentication:没有什么可以自动完成的,您可以向用户显示 500 HTTP 服务器错误,敲响警钟并让 devop 修复身份验证密钥

      这些基本上是您想要在内部定义然后适当捕获它们的异常类型。例如:

      ...
      catch (\Stripe\Error\ApiConnection $e) {
          trigger_error($e->getMessage(), E_USER_WARNING);
          throw new TransientError($e);
      }
      ...
      

    在这一切之后,您将减少对以下内容的 API 调用:

    try {
        return makeStripeApiCall('charge', $args);
    } catch (BadRequestError $e) {
        echo 'Card number invalid: ', $e->getMessage();
    }
    // don't catch other kinds of exception here,
    // let a higher up caller worry about graver issues
    

    【讨论】:

    • 感谢您的回答 - 它非常有用。我遇到的主要问题是传递方法,因为 try 块会有很大差异。它可能是收费、检索客户、创建订阅、更改订阅计划、添加优惠券 - 所有这些都具有不同的参数和元数据。
    • 匿名函数应该是最灵活的。
    • 谢谢 - 我会调查一下
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 2012-08-25
    • 2020-08-17
    • 1970-01-01
    相关资源
    最近更新 更多