2013-07-19 2 views
25

Во время моего тестирования полоски сайта, я построил такой код:Ловля ошибок нашивки с Try/Выгодой методом 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(); 
} 

Проблема заключается в том, что иногда возникает ошибка с картой (не поймает по «уловным» аргументам, которые у меня есть), и «try» терпит неудачу, и страница сразу же отправляет ошибку на экране вместо перехода в «if» и перенаправляет обратно на checkout.php.

Как я должен структурировать обработку ошибок, чтобы получить ошибку и сразу перенаправить обратно на checkout.php и отобразить там ошибку?

Спасибо!


Ошибка брошено:

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

ответ

42

Я думаю, что есть больше, чем эти исключения (Stripe_InvalidRequestError и Stripe_Error), чтобы поймать.

Код ниже - от Stripe's web site. Возможно, эти дополнительные исключения, которые вы не учитывали, происходят, и ваш код не работает иногда.

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(); 
} 

Теперь вы будете ловить все возможные исключения, и вы можете отобразить сообщение об ошибке, как вы хотите. А также $ error6 для несвязанных исключений.

+0

Я добавил ошибку брошенную на экране. Он исходит из одной из ошибок обработки файлов Stripe. Вопрос будет в том, как я мог поймать ошибку сам, а затем перенаправить, а не бросать сообщение Stripe ... – samyb8

+0

Я редактировал код. Вы не учитывали все исключения (например, ** Stripe_CarError **), и поэтому вы не можете их поймать, чтобы отобразить собственное сообщение об ошибке. –

+1

Проблема в том, что код проходит через ApiRequestor.php (файл Stripe), и он вроде как терпит неудачу там и не продолжает проходить через мои «уловы» – samyb8

8

Возможно, я опаздываю на этот вопрос, но столкнулся с тем же вопросом и нашел это.

Вам просто нужно использовать класс «Stripe_Error».

use Stripe_Error; 

После объявления, что я смог успешно поймать ошибки.

+0

Мне пришлось использовать «use \ Stripe_CardError и использовать \ Stripe_Error». –

55

Если вы используете нашивки PHP библиотеки, и они были в пространстве имен (например, когда они установлены с помощью Composer), вы можете перехватывать все исключения нашивки с:

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

Желание я мог бы увеличить ... – superphonic

+1

См. Другой ответ (http://stackoverflow.com/a/17750537/470749), который относится к документам Stripe (https://stripe.com/docs/api?lang = php # errors), которые показывают разные объекты ошибок для catch. 'Stripe \ Error \ Base' недостаточно. – Ryan

+4

@Ryan все классы ошибок Stripe наследуют от 'Stripe \ Error \ Base', а первый блок' catch' будет соответствовать всем этим подклассам. Я добавил второй «catch», который является более надежным и обрабатывает случаи, когда вызов Stripe API не возвращает исключение Stripe. – leepowers

5

Это обновление к другому ответ, но документы были слегка изменены, так что я имел успех, используя следующий метод:

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 
} 

Вы можете найти источник этого в Stripe документы прямо здесь:

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

2

Я думаю, что все, что вам действительно нужно проверить, это базовый класс ошибок Stripe и исключение, если оно не связано с Stripe. Вот как я это делаю.

/** 
* 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()' и 'getHttpStatus()' являются функциями stripe и не применяются при поиске стандартного исключения. – xinthose

3

Это как нашивка ловит ошибки в 2017. Documentation. Этот фрагмент требует 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; 
} 

Вы можете поймать ошибку в AJAX с помощью следующего кода:

$(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."); 
    } 
});