抽象 try/catch PHP - 条带错误处理

Abstracting try/catch PHP - stripe error handling

我正在处理来自 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

有一个函数可以为您处理:

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. 错误的请求,例如card declined: 您想直接在调用业务逻辑代码中捕获这些错误并根据具体问题做一些事情

    2. 服务中断,例如Stripe\Error\ApiConnection 或速率限制:除了稍后再试,你不能对这些做太多事情,你会想在更高的地方捕获这些错误并向用户显示 "sorry, try again later" 消息

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

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

    ...
    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