2013-07-19 13 views
25

Durante il mio test di STRISCIA in un sito web, ho costruito il codice come questo:Catching errori della banda con il try/catch metodo 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(); 
} 

Il problema è che a volte c'è un errore con la scheda (non catched con gli argomenti "catch" che ho lì) e il "try" fallisce e la pagina pubblica immediatamente l'errore nello schermo invece di entrare nel "se" e reindirizzare nuovamente a checkout.php.

Come devo strutturare la gestione degli errori in modo da ottenere l'errore e immediatamente reindirizzare nuovamente a checkout.php e visualizzare l'errore lì?

Grazie!


errore gettato:

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

risposta

42

penso che ci sia più di queste eccezioni (Stripe_InvalidRequestError e Stripe_Error) per prendere.

Il codice di seguito è da Stripe's web site. Probabilmente, queste eccezioni aggiuntive, che non hai preso in considerazione, si verificano e il tuo codice non funziona a volte.

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

Ora, si cattura tutte le eccezioni possibili e si può visualizzare il messaggio di errore come si desidera. E anche $ error6 è per eccezioni non correlate.

+0

ho aggiunto l'errore gettato su schermo. Viene da uno degli errori di gestione dei file Stripe. La domanda sarebbe, come ho potuto rilevare l'errore me stesso e poi reindirizzare, invece di lanciare il messaggio di Stripe ... – samyb8

+0

Ho modificato il codice. Non hai considerato tutte le eccezioni (ad esempio ** Stripe_CarError **) e quindi non puoi prenderle tutte per visualizzare il tuo messaggio di errore. –

+1

Il problema è che il codice passa attraverso ApiRequestor.php (il file di Stripe) e in questo modo fallisce e non continua a passare attraverso i miei "fermi" – samyb8

8

Potrei essere in ritardo a questa domanda, ma mi sono imbattuto nello stesso problema e ho trovato questo.

Hai solo bisogno di usare la classe "Stripe_Error".

use Stripe_Error; 

Dopo averlo dichiarato, sono riuscito a rilevare gli errori correttamente.

+0

Ho dovuto usare "use \ Stripe_CardError e usare \ Stripe_Error". –

55

Se stai usando le librerie PHP banda e sono stati namespace (come ad esempio quando sono installati tramite Compositore) si può prendere tutte le eccezioni della banda con:

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

Vorrei poter invocare altro ... – superphonic

+1

Vedere l'altra risposta (http://stackoverflow.com/a/17750537/470749), che si riferisce ai documenti Stripe (https://stripe.com/docs/api?lang = errori php #), che mostrano i diversi oggetti di errore da catturare. 'Stripe \ Error \ Base' non è abbastanza. – Ryan

+4

@Ryan tutte le classi di errore Stripe ereditano da 'Stripe \ Error \ Base', e il primo blocco' catch' corrisponderà a tutte queste sottoclassi. Ho aggiunto un secondo 'catch' che è più robusto e gestisce casi in cui una chiamata API Stripe non restituisce un'eccezione Stripe. – leepowers

5

Questo è un aggiornamento ad un altro risposta, ma la documentazione sono cambiati molto poco quindi ho avuto successo con il seguente metodo:

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 
} 

È possibile trovare la fonte di questo nei documenti Stripe proprio qui:

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

2

Penso che tutto ciò che è veramente necessario controllare sia la classe di errore di base di Stripe e l'eccezione se non è correlata a Stripe. Ecco come lo faccio.

/** 
* 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()' e 'getHttpStatus()' sono funzioni stripe e non si applicano quando si cattura l'eccezione standard. – xinthose

3

Questo è il modo in banda cattura errori nel 2017. Documentation. Questo snippet richiede 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; 
} 

È quindi possibile rilevare l'errore in Ajax con il seguente codice:

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