Awight has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/344042 )
Change subject: [WIP] Encapsulate errors ...................................................................... [WIP] Encapsulate errors TODO: * Figure out how to represent validation errors and internal errors under a polymorphic base. * Write has* and clear* accessors. * Write i18n glue. Figure out how to store messages that take params. Change-Id: I39bcc0c84609e681fb9c15db51058ee3ccd7fad8 --- A gateway_common/PaymentError.php M gateway_common/PaymentResult.php M gateway_common/PaymentTransactionResponse.php M gateway_common/gateway.adapter.php 4 files changed, 67 insertions(+), 85 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/DonationInterface refs/changes/42/344042/1 diff --git a/gateway_common/PaymentError.php b/gateway_common/PaymentError.php new file mode 100644 index 0000000..e1f90bc --- /dev/null +++ b/gateway_common/PaymentError.php @@ -0,0 +1,13 @@ +<?php + +class PaymentsError { + protected $error_code; + protected $debug_message; + protected $log_level; + + function __construct__( $error_code, $debug_message, $log_level ) { + $this->error_code = $error_code; + $this->debug_message = $debug_message; + $this->log_level = $log_level; + } +} diff --git a/gateway_common/PaymentResult.php b/gateway_common/PaymentResult.php index 77acb8f..ac73e9e 100644 --- a/gateway_common/PaymentResult.php +++ b/gateway_common/PaymentResult.php @@ -73,9 +73,9 @@ public static function newEmpty() { $response = new PaymentResult(); - $response->errors = array( - 'internal-0000' => 'Internal error: no results yet.', - ); + $response->errors = array( new PaymentError( + 'internal-0000', 'Internal error: no results yet.' + ) ); $response->failed = true; return $response; } diff --git a/gateway_common/PaymentTransactionResponse.php b/gateway_common/PaymentTransactionResponse.php index a116db3..f903af8 100644 --- a/gateway_common/PaymentTransactionResponse.php +++ b/gateway_common/PaymentTransactionResponse.php @@ -7,12 +7,7 @@ */ class PaymentTransactionResponse { /** - * @var array keys are error codes, values are themselves arrays of the form - * 'message' => 'for public consumption', - * 'debugInfo' => 'diagnostic information', - * 'logLevel' => LogLevel::WARNING - * If there weren't any, this should be present and empty after a - * transaction. + * @var array List of PaymentErrors */ protected $errors = array(); @@ -107,19 +102,18 @@ } /** - * @param array $errors + * @param array $errors List of PaymentError */ - public function setErrors( $errors ) { - $this->errors = $errors; + public function addErrors( $errors ) { + $this->errors += $errors; } /** * Add an error to the internal $errors array - * @param string $code identifies the error type - * @param array $error as specified in @see errors + * @param PaymentError $error */ - public function addError( $code, $error ) { - $this->errors[$code] = $error; + public function addError( $error ) { + $this->errors[] = $error; } /** diff --git a/gateway_common/gateway.adapter.php b/gateway_common/gateway.adapter.php index 8eb8861..de8b23d 100644 --- a/gateway_common/gateway.adapter.php +++ b/gateway_common/gateway.adapter.php @@ -144,6 +144,8 @@ /** * $transaction_response is the member var that keeps track of the results of * the latest discrete transaction with the gateway. + * TODO: We might want to deprecate this and pass out of do_transaction + * using functional style. * @var PaymentTransactionResponse */ protected $transaction_response; @@ -153,16 +155,7 @@ */ protected $final_status; /** - * @var array Map of errors preventing this transaction from continuing. - * Structure is like: - * [ - * # An i18n key name to an error message that will display atop of - * # the screen, indicating that something general needs fixing. - * 'general' => 'warning-currency-fallback', - * # Example of a very specific error string that only the gateway - * # could calculate. - * 'address' => 'key saying: "Address is required for E-Commerce transactions."', - * ] + * @var array PaymentError[] List of errors preventing this transaction from continuing. */ protected $errors = array(); @@ -908,16 +901,13 @@ $this->session_addDonorData(); if ( !$this->validatedOK() ){ //If the data didn't validate okay, prevent all data transmissions. - // TODO: Rename variable to "response". - $return = new PaymentTransactionResponse(); - $return->setCommunicationStatus( false ); - $return->setMessage( 'Failed data validation' ); - foreach ( $this->errors as $code => $error ) { - $return->addError( $code, array( 'message' => $error, 'logLevel' => LogLevel::INFO, 'debugInfo' => '' ) ); - } // TODO: should we set $this->transaction_response ? + $response = new PaymentTransactionResponse(); + $response->setCommunicationStatus( false ); + $response->setMessage( 'Failed data validation' ); + $response->addErrors( $this->errors ); $this->logger->info( "Failed Validation. Aborting $transaction " . print_r( $this->errors, true ) ); - return $return; + return $response; } $retryCount = 0; @@ -964,7 +954,7 @@ * * post_process_<strtolower($transaction)> * * @param string $transaction Name of the transaction being performed - * @param &string() $retryVars Reference to an array of variables that caused the + * @param &string[] $retryVars Reference to an array of variables that caused the * transaction to fail. * * @return PaymentTransactionResponse @@ -988,12 +978,10 @@ $this->logger->info( "Failed pre-process checks for transaction type $transaction." ); $this->transaction_response->setCommunicationStatus( false ); $this->transaction_response->setMessage( $this->getErrorMapByCodeAndTranslate( 'internal-0000' ) ); - $this->transaction_response->setErrors( array( - 'internal-0000' => array( - 'debugInfo' => "Failed pre-process checks for transaction type $transaction.", - 'message' => $this->getErrorMapByCodeAndTranslate( 'internal-0000' ), - 'logLevel' => LogLevel::INFO - ) + $this->transaction_response->addError( new PaymentsError( + 'internal-0000', + "Failed pre-process checks for transaction type $transaction.", + LogLevel::INFO ) ); return $this->transaction_response; } @@ -1042,12 +1030,10 @@ $this->transaction_response->setCommunicationStatus( false ); $this->transaction_response->setMessage( $this->getErrorMapByCodeAndTranslate( 'internal-0001' ) ); - $this->transaction_response->setErrors( array( - 'internal-0001' => array( - 'debugInfo' => 'Malformed gateway definition. Cannot continue: Aborting.\n' . $e->getMessage(), - 'message' => $this->getErrorMapByCodeAndTranslate( 'internal-0001' ), - 'logLevel' => LogLevel::CRITICAL - ) + $this->transaction_response->addError( new PaymentsError( + 'internal-0001', + 'Malformed gateway definition. Cannot continue: Aborting.\n' . $e->getMessage(), + LogLevel::CRITICAL ) ); return $this->transaction_response; @@ -1066,12 +1052,13 @@ try { $this->processResponse( $formatted ); } catch ( ResponseProcessingException $ex ) { + // TODO: Should we integrate ResponseProcessingException with PaymentsError? $errCode = $ex->getErrorCode(); $retryVars = $ex->getRetryVars(); - $this->transaction_response->addError( $errCode, array( - 'message' => $this->getErrorMapByCodeAndTranslate( $errCode ), - 'debugInfo' => $ex->getMessage(), - 'logLevel' => LogLevel::ERROR + $this->transaction_response->addError( new PaymentsError( + $errCode, + $ex->getMessage(), + LogLevel::ERROR ) ); } @@ -1081,12 +1068,10 @@ $this->transaction_response->setCommunicationStatus( false ); $this->transaction_response->setMessage( $this->getErrorMapByCodeAndTranslate( 'internal-0002' ) ); - $this->transaction_response->setErrors( array( - 'internal-0002' => array( - 'debugInfo' => $logMessage, - 'message' => $this->getErrorMapByCodeAndTranslate( 'internal-0002' ), - 'logLevel' => LogLevel::ERROR - ) + $this->transaction_response->addError( new PaymentsError( + 'internal-0002' + $logMessage, + LogLevel::ERROR ) ); } @@ -1099,12 +1084,10 @@ // Set this by key so that the result object still has all the cURL data $this->transaction_response->setCommunicationStatus( false ); $this->transaction_response->setMessage( $this->getErrorMapByCodeAndTranslate( $errCode ) ); - $this->transaction_response->setErrors( array( - $errCode => array( - 'debugInfo' => "$transaction Communication failed (errcode $errCode), will reattempt!", - 'message' => $this->getErrorMapByCodeAndTranslate( $errCode ), - 'logLevel' => LogLevel::CRITICAL - ) + $this->transaction_response->addError( new PaymentsError( + $errCode + "$transaction Communication failed (errcode $errCode), will reattempt!", + LogLevel::CRITICAL ) ); } @@ -1126,12 +1109,10 @@ $this->logger->info( "Failed post-process checks for transaction type $transaction." ); $this->transaction_response->setCommunicationStatus( false ); $this->transaction_response->setMessage( $this->getErrorMapByCodeAndTranslate( 'internal-0000' ) ); - $this->transaction_response->setErrors( array( - 'internal-0000' => array( - 'debugInfo' => "Failed post-process checks for transaction type $transaction.", - 'message' => $this->getErrorMapByCodeAndTranslate( 'internal-0000' ), - 'logLevel' => LogLevel::INFO - ) + $this->transaction_response->addError( new PaymentsError( + 'internal-0000', + "Failed post-process checks for transaction type $transaction.", + LogLevel::INFO ) ); return $this->transaction_response; } @@ -2129,11 +2110,8 @@ */ public function getTransactionErrors() { - if ( $this->transaction_response && $this->transaction_response->getErrors() ) { - $simplify = function( $error ) { - return $error['message']; - }; - return array_map( $simplify, $this->transaction_response->getErrors() ); + if ( $this->transaction_response ) { + return $this->transaction_response->getErrors(); } else { return array(); } @@ -2162,15 +2140,10 @@ /** * Add errors those already stored. * - * @param array $errors Map from field or field group key to error string. - * May contain one or multiple erroring fields. - * Merged by key rather than as a list, hence the awkward, surprise plural. - * - * TODO: Encapsulate errors as objects. Provide both merge list and append item to list methods? - * FIXME: Nasty that array_merge overwrites rather than appending. Fix while encapsulating the list. + * @param array $errors List of PaymentErrors. */ - public function mergeError( $errors ) { - $this->errors = array_merge( $this->errors, $errors ); + public function addErrors( $errors ) { + $this->errors += $errors; } /** @@ -2463,7 +2436,7 @@ } // TODO: Rewrite as something modular? It's in-between validation and normalization... - if ( isset( $this->errors['currency_code'] ) ) { + if ( $this->hasValidationError( 'currency_code' ) ) { // Try to fall back to a default currency, clearing the error if // successful. $this->fallbackToDefaultCurrency(); @@ -2545,7 +2518,7 @@ $this->logger->info( "Unsupported currency $oldCurrency forced to $defaultCurrency" ); // Clear the currency error. - unset( $this->errors['currency_code'] ); + $this->clearValidationError( 'currency_code' ); $notify = $this->getGlobal( 'NotifyOnConvert' ); @@ -2558,7 +2531,9 @@ $this->dataObj->getVal( 'language' ), array( $defaultCurrency ) ); - $this->mergeError( $error ); + $this->addError( new ValidationError( + //XXX + ) ); } } -- To view, visit https://gerrit.wikimedia.org/r/344042 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I39bcc0c84609e681fb9c15db51058ee3ccd7fad8 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/DonationInterface Gerrit-Branch: master Gerrit-Owner: Awight <awi...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits