2013-07-19 28 views
25

Trong thử nghiệm của tôi về STRIPE trong một trang web, tôi đã xây dựng các mã như thế này:Bắt lỗi sọc với try/catch phương pháp PHP

try { 
     $charge = Stripe_Charge::create(array(
      "amount" => $clientPriceStripe, // amount in cents 
      "currency" => "usd", 
      "customer" => $customer->id, 
      "description" => $description)); 
      $success = 1; 
      $paymentProcessor="Credit card (www.stripe.com)"; 
    } 
    catch (Stripe_InvalidRequestError $a) { 
     // Since it's a decline, Stripe_CardError will be caught 
     $error3 = $a->getMessage(); 
    } 

    catch (Stripe_Error $e) { 
     // Since it's a decline, Stripe_CardError will be caught 
     $error2 = $e->getMessage(); 
     $error = 1; 
    } 
if ($success!=1) 
{ 
    $_SESSION['error3'] = $error3; 
    $_SESSION['error2'] = $error2; 
    header('Location: checkout.php'); 
    exit(); 
} 

Vấn đề là đôi khi có lỗi với các thẻ (không đánh bắt bởi các đối số "bắt" tôi có) và "try" thất bại và trang ngay lập tức đăng lỗi trong màn hình thay vì đi vào "if" và chuyển hướng trở lại checkout.php.

Tôi nên cấu trúc xử lý lỗi của mình như thế nào để nhận được lỗi và ngay lập tức chuyển hướng trở lại checkout.php và hiển thị lỗi ở đó?

Cảm ơn!


Lỗi được tạo ra:

Fatal error: Uncaught exception 'Stripe_CardError' with message 'Your card was declined.' in ............ 
/lib/Stripe/ApiRequestor.php on line 92 

Trả lời

42

Tôi nghĩ rằng có nhiều hơn những trường hợp ngoại lệ (Stripe_InvalidRequestErrorStripe_Error) để bắt.

Mã bên dưới là từ Stripe's web site. Có thể, những ngoại lệ bổ sung này, mà bạn không xem xét, xảy ra và mã của bạn không thành công đôi khi.

try { 
    // Use Stripe's bindings... 
} catch(Stripe_CardError $e) { 
    // Since it's a decline, Stripe_CardError 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_InvalidRequestError $e) { 
    // Invalid parameters were supplied to Stripe's API 
} catch (Stripe_AuthenticationError $e) { 
    // Authentication with Stripe's API failed 
    // (maybe you changed API keys recently) 
} catch (Stripe_ApiConnectionError $e) { 
    // Network communication with Stripe failed 
} catch (Stripe_Error $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 
} 

EDIT:

try { 
    $charge = Stripe_Charge::create(array(
    "amount" => $clientPriceStripe, // amount in cents 
    "currency" => "usd", 
    "customer" => $customer->id, 
    "description" => $description)); 
    $success = 1; 
    $paymentProcessor="Credit card (www.stripe.com)"; 
} catch(Stripe_CardError $e) { 
    $error1 = $e->getMessage(); 
} catch (Stripe_InvalidRequestError $e) { 
    // Invalid parameters were supplied to Stripe's API 
    $error2 = $e->getMessage(); 
} catch (Stripe_AuthenticationError $e) { 
    // Authentication with Stripe's API failed 
    $error3 = $e->getMessage(); 
} catch (Stripe_ApiConnectionError $e) { 
    // Network communication with Stripe failed 
    $error4 = $e->getMessage(); 
} catch (Stripe_Error $e) { 
    // Display a very generic error to the user, and maybe send 
    // yourself an email 
    $error5 = $e->getMessage(); 
} catch (Exception $e) { 
    // Something else happened, completely unrelated to Stripe 
    $error6 = $e->getMessage(); 
} 

if ($success!=1) 
{ 
    $_SESSION['error1'] = $error1; 
    $_SESSION['error2'] = $error2; 
    $_SESSION['error3'] = $error3; 
    $_SESSION['error4'] = $error4; 
    $_SESSION['error5'] = $error5; 
    $_SESSION['error6'] = $error6; 
    header('Location: checkout.php'); 
    exit(); 
} 

Bây giờ, bạn sẽ bắt tất cả các trường hợp ngoại lệ có thể và bạn có thể hiển thị thông báo lỗi như bạn muốn. Và cũng $ error6 là cho các trường hợp ngoại lệ không liên quan.

+0

tôi đã thêm lỗi ném trên màn hình. Nó xuất phát từ một trong các lỗi xử lý tệp Stripe. Câu hỏi đặt ra là, làm cách nào tôi có thể tự mình bắt lỗi và sau đó chuyển hướng, thay vì gửi thông điệp của Stripe ... – samyb8

+0

Tôi đã chỉnh sửa mã. Bạn không xem xét tất cả các trường hợp ngoại lệ (ví dụ ** Stripe_CarError **) và vì vậy bạn không thể bắt tất cả ngoại lệ để hiển thị thông báo lỗi của riêng bạn. –

+1

Vấn đề là mã đi qua ApiRequestor.php (tập tin của Stripe) và nó không thành công ở đó và không tiếp tục đi qua "catches" của tôi – samyb8

8

Tôi có thể bị trễ câu hỏi này, nhưng tôi đã gặp phải vấn đề tương tự và thấy điều này.

Bạn chỉ cần sử dụng lớp "Stripe_Error".

use Stripe_Error; 

Sau khi khai báo, tôi đã có thể phát hiện lỗi thành công.

+0

Tôi đã phải sử dụng "sử dụng \ Stripe_CardError và sử dụng \ Stripe_Error". –

55

Nếu bạn đang sử dụng các thư viện sọc PHP và họ đã được namespaced (chẳng hạn như khi họ đang được cài đặt thông qua Composer), bạn có thể bắt tất cả các trường hợp ngoại lệ sọc với:

<?php 
try { 
    // Use a Stripe PHP library method that may throw an exception.... 
    \Stripe\Customer::create($args); 
} catch (\Stripe\Error\Base $e) { 
    // Code to do something with the $e exception object when an error occurs 
    echo($e->getMessage()); 
} catch (Exception $e) { 
    // Catch any other non-Stripe exceptions 
} 
+3

Ước gì tôi có thể upvote nhiều hơn ... – superphonic

+1

Xem câu trả lời khác (http://stackoverflow.com/a/17750537/470749), đề cập đến tài liệu Stripe (https://stripe.com/docs/api?lang = php # lỗi), hiển thị các đối tượng lỗi khác nhau để bắt. 'Stripe \ Error \ Base' là không đủ. – Ryan

+4

@Ryan tất cả các lớp lỗi Sọc kế thừa từ 'Stripe \ Error \ Base' và khối' catch' đầu tiên sẽ khớp với tất cả các lớp con này. Tôi đã thêm một 'catch' thứ hai mạnh hơn và xử lý các trường hợp mà một cuộc gọi API Stripe không trả về một ngoại lệ Stripe. – leepowers

5

Đây là một bản cập nhật khác câu trả lời, nhưng các tài liệu đã thay đổi rất nhẹ vì vậy tôi đã thành công bằng cách sử dụng phương pháp sau đây:

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 
} 

Bạn có thể tìm ra nguồn gốc của này trong các tài liệu Stripe ngay tại đây:

https://stripe.com/docs/api?lang=php#handling-errors

2

Tôi nghĩ rằng tất cả những gì bạn thực sự cần kiểm tra là lớp lỗi cơ bản của Stripe và ngoại lệ nếu nó không liên quan đến Stripe. Đây là cách tôi làm điều đó.

/** 
* Config. 
*/ 
require_once(dirname(__FILE__) . '/config.php'); 

// Hit Stripe API. 
try { 
    // Register a Customer. 
    $customer = \Stripe\Customer::create(array(
    'email' => '[email protected]', 
    'source' => $token, 
    'metadata' => array(// Note: You can specify up to 20 keys, with key names up to 40 characters long and values up to 500 characters long. 
     'NAME'   => 'AA', 
     'EMAIL'   => '[email protected]', 
     'ORDER DETAILS' => $order_details, 
    ) 
)); 

    // Charge a customer. 
    $charge = \Stripe\Charge::create(array(
    'customer' => $customer->id, 
    'amount' => 5000, // In cents. 
    'currency' => 'usd' 
)); 



    // If there is an error from Stripe. 
} catch (Stripe\Error\Base $e) { 
    // Code to do something with the $e exception object when an error occurs. 
    echo $e->getMessage(); 

    // DEBUG. 
    $body = $e->getJsonBody(); 
    $err = $body['error']; 
    echo '<br> ——— <br>'; 
    echo '<br>THE ERROR DEFINED — <br>'; 
    echo '— Status is: ' . $e->getHttpStatus() . '<br>'; 
    echo '— Message is: ' . $err['message'] . '<br>'; 
    echo '— Type is: ' . $err['type'] . '<br>'; 
    echo '— Param is: ' . $err['param'] . '<br>'; 
    echo '— Code is: ' . $err['code'] . '<br>'; 
    echo '<br> ——— <br>'; 

// Catch any other non-Stripe exceptions. 
} catch (Exception $e) { 
    $body = $e->getJsonBody(); 
    $err = $body['error']; 
    echo '<br> ——— <br>'; 
    echo '<br>THE ERROR DEFINED — <br>'; 
    echo '— Status is: ' . $e->getHttpStatus() . '<br>'; 
    echo '— Message is: ' . $err['message'] . '<br>'; 
    echo '— Type is: ' . $err['type'] . '<br>'; 
    echo '— Param is: ' . $err['param'] . '<br>'; 
    echo '— Code is: ' . $err['code'] . '<br>'; 
    echo '<br> ——— <br>'; 
} 
+0

'getJsonBody()' và 'getHttpStatus()' là các hàm sọc và không áp dụng khi bắt ngoại lệ tiêu chuẩn. – xinthose

3

Đây là cách Stripe phát hiện lỗi trong năm 2017. Documentation. Đoạn mã này yêu cầu PHP 7.1+

catch(\Stripe\Error\Card | \Stripe\Error\RateLimit | \Stripe\Error\InvalidRequest | \Stripe\Error\Authentication | \Stripe\Error\ApiConnection $e) 
{ 
    $body = $e->getJsonBody(); 
    $err = $body["error"]; 
    $return_array = [ 
     "status" => $e->getHttpStatus(), 
     "type" => $err["type"], 
     "code" => $err["code"], 
     "param" => $err["param"], 
     "message" => $err["message"], 
    ]; 
    $return_str = json_encode($return_array);   
    http_response_code($e->getHttpStatus()); 
    echo $return_str; 
} 

Sau đó bạn có thể bắt lỗi trong ajax với đoạn mã sau:

$(document).ajaxError(function ajaxError(event, jqXHR, ajaxSettings, thrownError) { 
    try { 
     var url = ajaxSettings.url; 
     var http_status_code = jqXHR.status; 
     var response = jqXHR.responseText; 
     var message = ""; 
     if (isJson(response)) {  // see here for function: https://stackoverflow.com/a/32278428/4056146 
      message = " " + (JSON.parse(response)).message; 
     } 
     var error_str = ""; 

     // 1. handle HTTP status code 
     switch (http_status_code) { 
      case 0: { 
       error_str = "No Connection. Cannot connect to " + new URL(url).hostname + "."; 
       break; 
      } // No Connection 
      case 400: { 
       error_str = "Bad Request." + message + " Please see help."; 
       break; 
      } // Bad Request 
      case 401: { 
       error_str = "Unauthorized." + message + " Please see help."; 
       break; 
      } // Unauthorized 
      case 402: { 
       error_str = "Request Failed." + message; 
       break; 
      } // Request Failed 
      case 404: { 
       error_str = "Not Found." + message + " Please see help."; 
       break; 
      } // Not Found 
      case 405: { 
       error_str = "Method Not Allowed." + message + " Please see help."; 
       break; 
      } // Method Not Allowed 
      case 409: { 
       error_str = "Conflict." + message + " Please see help."; 
       break; 
      } // Conflict 
      case 429: { 
       error_str = "Too Many Requests." + message + " Please try again later."; 
       break; 
      } // Too Many Requests 
      case 500: { 
       error_str = "Internal Server Error." + message + " Please see help."; 
       break; 
      } // Internal Server Error 
      case 502: { 
       error_str = "Bad Gateway." + message + " Please see help."; 
       break; 
      } // Bad Gateway 
      case 503: { 
       error_str = "Service Unavailable." + message + " Please see help."; 
       break; 
      } // Service Unavailable 
      case 504: { 
       error_str = "Gateway Timeout." + message + " Please see help."; 
       break; 
      } // Gateway Timeout 
      default: { 
       console.error(loc + "http_status_code unhandled >> http_status_code = " + http_status_code); 
       error_str = "Unknown Error." + message + " Please see help."; 
       break; 
      } 
     } 

     // 2. show popup 
     alert(error_str); 
     console.error(arguments.callee.name + " >> http_status_code = " + http_status_code.toString() + "; thrownError = " + thrownError + "; URL = " + url + "; Response = " + response); 

    } 
    catch (e) { 
     console.error(arguments.callee.name + " >> ERROR >> " + e.toString()); 
     alert("Internal Error. Please see help."); 
    } 
});