2017-07-30 33 views
2

我正在使用Stripe.js元素旋轉應用程序。使用Stripe提供的測試卡號碼,我沒有問題。所有按預期工作。如何在PHP中捕捉到條帶致命錯誤?

我現在專注於錯誤處理。當使用測試卡4000 0000 0000技術來處理卡是刻意地拒絕,我得到這個錯誤:

Fatal error: Uncaught Stripe\Error\Card: Your card was declined. in C:\Apache24\htdocs...\vendor\stripe\stripe-php\lib\ApiRequestor.php:128 from API request {token}....

現在,我猜想這是不是一個PHP致命錯誤(不能在處理try/catch塊),所以我搜查,發現this example並實現它變成我這樣的代碼:

\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 
     } 

這不,但是,捕獲的錯誤。該消息繼續顯示,因爲它是在我有捕獲塊之前。

任何線索爲什麼我得到致命錯誤?當然,我預計這張卡會被拒絕,但我預計這個下降的結果是我能夠在try/catch塊中處理的。

編輯

我要補充一點,我使用的作曲家包括條紋PHP庫。

進一步注意:它可能不相關,但對於所有應該被拒絕的測試卡都會顯示致命錯誤消息。下降的原因在每張卡的錯誤信息中都有明確說明,例如(不是逐字)郵政編碼驗證失敗,CVC不正確,卡過期等。

正如@Ywain正確地指出,這實際上並不是嘗試/ catch塊問題。致命錯誤首先由收費交易產生。換句話說,對\ Stripe \ Charge的調用應該返回一個帶有相應標誌或字段值的JSON數組,而不是一個致命錯誤。

+0

'\條\錯誤\ Base'是所有條紋錯誤的父類,所以如果你先抓住它,沒有其他的'\條\錯誤\的... \'catch子句就會執行。你應該只在倒數第二個(在Exception之前,但在所有其他catch子句之後)捕獲它。 也就是說,如果沒有任何catch子句被執行,儘管出現了錯誤消息,最可能的解釋是運行的代碼與您正在查看並複製到此處的代碼不同。 – Ywain

+0

@Ywain - 我嘗試過許多不同方式的代碼。沒有任何try/catch,我也會得到相同的結果。所以你提出了一個很好的觀點:雖然try/catch塊可能不是「spec」,但它確實不是問題。我將重新編輯帖子以反映這一點。任何線索? – globalSchmidt

回答

0

我認爲你需要捕捉不同類型的拋出錯誤。

\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 
    } 
+0

好抓!雖然沒有改變。仍然收到相同的致命錯誤消息。 – globalSchmidt

+0

這可能是一個愚蠢的問題,但是路徑\ Stripe \ Error \ *有效嗎?想要確保它能夠看到這些類。 –

+0

好吧,條紋是通過作曲家,所以我沒有移動或觸及任何文件。我假設(因爲它在Stripe文檔中)\ Stripe \ Error \ {whatever]是有效的引用。錯誤確實指的是stripe \ stripe-php \ lib \ ApiRequestor.php第128行,它處理類似於這樣的402錯誤:case 402: 返回新的Error \ Card($ msg,$ param,$ code,$ rcode ,$ rbody,$ resp,$ rheaders);'除了說'Error \ Card'外沒什麼幫助。 – globalSchmidt

3

條帶有很多例外,它可以在交易過程中拋出。他們的API有優秀的sample code來提供捕獲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 
} 

也請記住,一旦你捕獲異常,除非你做一些專門結束腳本或變更執行路徑,你的腳本將繼續運行該代碼的其餘一無所知有任何異常上調。考慮這個過於簡單的例子。

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

該卡被拒絕並且api拋出\ Stripe \ Error \ Card。您然後收到以下輸出。

I had an error!I completed successfully

如果您的執行路徑中有多個API調用,這很重要。您可以很好地捕獲拋出的異常,以便稍後調用另一個您不期望運行的異常。您應該可以調用所有可能會引發try/catch中包含的異常的API。如果您希望從以前的調用中捕獲錯誤以防止其他代碼執行,那麼您還需要注意執行路徑。過於簡單的例子。

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"); 
} 
+0

這正是我開始的地方......這些都沒有發現「致命錯誤」。這非常令人沮喪。 – globalSchmidt

+0

你碰巧有其他調用不在try/catch塊中的stripe api嗎?我提到它,因爲我有一天有同樣的問題。他們在第一次電話會議上發現了異常情況,但是從來沒有退出他們的腳本,導致第二次調用進一步導致錯誤。 –

+0

很高興知道,但沒有。這是我開始關注的第一個錯誤案例。沒有其他調用具有try/catch塊。 – globalSchmidt