summaryrefslogtreecommitdiffstats
path: root/components/autofill
diff options
context:
space:
mode:
authorahutter@chromium.org <ahutter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-16 05:15:18 +0000
committerahutter@chromium.org <ahutter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-16 05:15:18 +0000
commit56cb9ea4d5c4d3058cdc22622f1de5c28682f615 (patch)
treee4042547c9eedefae51f1587a399b340f99b103c /components/autofill
parent125abb32ec2957e070e5c6315b52a1697580b7ed (diff)
downloadchromium_src-56cb9ea4d5c4d3058cdc22622f1de5c28682f615.zip
chromium_src-56cb9ea4d5c4d3058cdc22622f1de5c28682f615.tar.gz
chromium_src-56cb9ea4d5c4d3058cdc22622f1de5c28682f615.tar.bz2
Using error returns from Online Wallet
BUG=164410 Review URL: https://chromiumcodereview.appspot.com/12545037 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188540 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'components/autofill')
-rw-r--r--components/autofill/browser/autofill_metrics.h21
-rw-r--r--components/autofill/browser/wallet/wallet_client.cc67
-rw-r--r--components/autofill/browser/wallet/wallet_client.h24
-rw-r--r--components/autofill/browser/wallet/wallet_client_delegate.h5
-rw-r--r--components/autofill/browser/wallet/wallet_client_unittest.cc83
5 files changed, 164 insertions, 36 deletions
diff --git a/components/autofill/browser/autofill_metrics.h b/components/autofill/browser/autofill_metrics.h
index d95aa29..1757486 100644
--- a/components/autofill/browser/autofill_metrics.h
+++ b/components/autofill/browser/autofill_metrics.h
@@ -192,12 +192,29 @@ class AutofillMetrics {
enum WalletErrorMetric {
// Baseline metric: Issued a request to the Wallet server.
WALLET_ERROR_BASELINE_ISSUED_REQUEST = 0,
- // A fatal error occured while communicating with the Wallet server.
- WALLET_FATAL_ERROR,
+ // A fatal error occured while communicating with the Wallet server. This
+ // value has been deprecated.
+ WALLET_FATAL_ERROR_DEPRECATED,
// Received a malformed response from the Wallet server.
WALLET_MALFORMED_RESPONSE,
// A network error occured while communicating with the Wallet server.
WALLET_NETWORK_ERROR,
+ // The request was malformed.
+ WALLET_BAD_REQUEST,
+ // Risk deny, unsupported country, or account closed.
+ WALLET_BUYER_ACCOUNT_ERROR,
+ // Unknown server side error.
+ WALLET_INTERNAL_ERROR,
+ // API call had missing or invalid parameters.
+ WALLET_INVALID_PARAMS,
+ // Online Wallet is down.
+ WALLET_SERVICE_UNAVAILABLE,
+ // User needs make a cheaper transaction or not use Online Wallet.
+ WALLET_SPENDING_LIMIT_EXCEEDED,
+ // The server API version of the request is no longer supported.
+ WALLET_UNSUPPORTED_API_VERSION,
+ // Catch all error type.
+ WALLET_UNKNOWN_ERROR,
NUM_WALLET_ERROR_METRICS
};
diff --git a/components/autofill/browser/wallet/wallet_client.cc b/components/autofill/browser/wallet/wallet_client.cc
index 9683eed..5df8ab4 100644
--- a/components/autofill/browser/wallet/wallet_client.cc
+++ b/components/autofill/browser/wallet/wallet_client.cc
@@ -70,6 +70,26 @@ std::string RiskCapabilityToString(
return "NOT_POSSIBLE";
}
+WalletClient::ErrorType StringToErrorType(const std::string& error_type) {
+ std::string trimmed;
+ TrimWhitespaceASCII(error_type,
+ TRIM_ALL,
+ &trimmed);
+ if (LowerCaseEqualsASCII(trimmed, "buyer_account_error"))
+ return WalletClient::BUYER_ACCOUNT_ERROR;
+ if (LowerCaseEqualsASCII(trimmed, "internal_error"))
+ return WalletClient::INTERNAL_ERROR;
+ if (LowerCaseEqualsASCII(trimmed, "invalid_params"))
+ return WalletClient::INVALID_PARAMS;
+ if (LowerCaseEqualsASCII(trimmed, "service_unavailable"))
+ return WalletClient::SERVICE_UNAVAILABLE;
+ if (LowerCaseEqualsASCII(trimmed, "spending_limit_exceeded"))
+ return WalletClient::SPENDING_LIMIT_EXCEEDED;
+ if (LowerCaseEqualsASCII(trimmed, "unsupported_api_version"))
+ return WalletClient::UNSUPPORTED_API_VERSION;
+ return WalletClient::UNKNOWN_ERROR;
+}
+
// Gets and parses required actions from a SaveToWallet response. Returns
// false if any unknown required actions are seen and true otherwise.
void GetRequiredActionsForSaveToWallet(
@@ -94,6 +114,33 @@ void GetRequiredActionsForSaveToWallet(
}
}
+// Converts the |error_type| to the corresponding value from the stable UMA
+// metric enumeration.
+AutofillMetrics::WalletErrorMetric ErrorTypeToUmaMetric(
+ WalletClient::ErrorType error_type) {
+ switch (error_type) {
+ case WalletClient::BAD_REQUEST:
+ return AutofillMetrics::WALLET_BAD_REQUEST;
+ case WalletClient::BUYER_ACCOUNT_ERROR:
+ return AutofillMetrics::WALLET_BUYER_ACCOUNT_ERROR;
+ case WalletClient::INTERNAL_ERROR:
+ return AutofillMetrics::WALLET_INTERNAL_ERROR;
+ case WalletClient::INVALID_PARAMS:
+ return AutofillMetrics::WALLET_INVALID_PARAMS;
+ case WalletClient::SERVICE_UNAVAILABLE:
+ return AutofillMetrics::WALLET_SERVICE_UNAVAILABLE;
+ case WalletClient::SPENDING_LIMIT_EXCEEDED:
+ return AutofillMetrics::WALLET_SPENDING_LIMIT_EXCEEDED;
+ case WalletClient::UNSUPPORTED_API_VERSION:
+ return AutofillMetrics::WALLET_UNSUPPORTED_API_VERSION;
+ case WalletClient::UNKNOWN_ERROR:
+ return AutofillMetrics::WALLET_UNKNOWN_ERROR;
+ }
+
+ NOTREACHED();
+ return AutofillMetrics::WALLET_UNKNOWN_ERROR;
+}
+
// Converts the |required_action| to the corresponding value from the stable UMA
// metric enumeration.
AutofillMetrics::WalletRequiredActionMetric RequiredActionToUmaMetric(
@@ -133,6 +180,7 @@ const char kApiKeyKey[] = "api_key";
const char kAuthResultKey[] = "auth_result";
const char kCartKey[] = "cart";
const char kEncryptedOtpKey[] = "encrypted_otp";
+const char kErrorTypeKey[] = "wallet_error.error_type";
const char kFeatureKey[] = "feature";
const char kGoogleTransactionIdKey[] = "google_transaction_id";
const char kInstrumentIdKey[] = "instrument_id";
@@ -529,7 +577,7 @@ void WalletClient::OnURLFetchComplete(
// HTTP_BAD_REQUEST means the arguments are invalid. No point retrying.
case net::HTTP_BAD_REQUEST: {
request_type_ = NO_PENDING_REQUEST;
- HandleWalletError();
+ HandleWalletError(WalletClient::BAD_REQUEST);
return;
}
// HTTP_OK holds a valid response and HTTP_INTERNAL_SERVER_ERROR holds an
@@ -544,9 +592,14 @@ void WalletClient::OnURLFetchComplete(
}
if (response_code == net::HTTP_INTERNAL_SERVER_ERROR) {
request_type_ = NO_PENDING_REQUEST;
- // TODO(ahutter): Do something with the response. See
- // http://crbug.com/164410.
- HandleWalletError();
+
+ std::string error_type;
+ if (!response_dict->GetString(kErrorTypeKey, &error_type)) {
+ HandleWalletError(WalletClient::UNKNOWN_ERROR);
+ return;
+ }
+
+ HandleWalletError(StringToErrorType(error_type));
return;
}
break;
@@ -712,10 +765,10 @@ void WalletClient::HandleNetworkError(int response_code) {
delegate_->GetDialogType(), AutofillMetrics::WALLET_NETWORK_ERROR);
}
-void WalletClient::HandleWalletError() {
- delegate_->OnWalletError();
+void WalletClient::HandleWalletError(WalletClient::ErrorType error_type) {
+ delegate_->OnWalletError(error_type);
delegate_->GetMetricLogger().LogWalletErrorMetric(
- delegate_->GetDialogType(), AutofillMetrics::WALLET_FATAL_ERROR);
+ delegate_->GetDialogType(), ErrorTypeToUmaMetric(error_type));
}
void WalletClient::OnDidEncryptOneTimePad(
diff --git a/components/autofill/browser/wallet/wallet_client.h b/components/autofill/browser/wallet/wallet_client.h
index 0032a6c..7fd02fc 100644
--- a/components/autofill/browser/wallet/wallet_client.h
+++ b/components/autofill/browser/wallet/wallet_client.h
@@ -73,6 +73,28 @@ class WalletClient
VERIFY_CVC,
};
+ // The type of error returned by Online Wallet.
+ enum ErrorType {
+ // Errors to display to users.
+ BUYER_ACCOUNT_ERROR, // Risk deny, unsupported country, or account
+ // closed.
+ SPENDING_LIMIT_EXCEEDED, // User needs make a cheaper transaction or not
+ // use Online Wallet.
+
+ // API errors.
+ BAD_REQUEST, // Request was very malformed or sent to the
+ // wrong endpoint.
+ INVALID_PARAMS, // API call had missing or invalid parameters.
+ UNSUPPORTED_API_VERSION, // The server API version of the request is no
+ // longer supported.
+
+ // Server errors.
+ INTERNAL_ERROR, // Unknown server side error.
+ SERVICE_UNAVAILABLE, // Online Wallet is down.
+
+ UNKNOWN_ERROR, // Catch all error type.
+ };
+
struct FullWalletRequest {
public:
FullWalletRequest(const std::string& instrument_id,
@@ -204,7 +226,7 @@ class WalletClient
// Performs bookkeeping tasks for any invalid requests.
void HandleMalformedResponse();
void HandleNetworkError(int response_code);
- void HandleWalletError();
+ void HandleWalletError(ErrorType error_type);
// Start the next pending request (if any).
void StartNextPendingRequest();
diff --git a/components/autofill/browser/wallet/wallet_client_delegate.h b/components/autofill/browser/wallet/wallet_client_delegate.h
index 23cb417..5b25b36 100644
--- a/components/autofill/browser/wallet/wallet_client_delegate.h
+++ b/components/autofill/browser/wallet/wallet_client_delegate.h
@@ -9,6 +9,7 @@
#include "base/memory/scoped_ptr.h"
#include "components/autofill/browser/autofill_manager_delegate.h"
+#include "components/autofill/browser/wallet/wallet_client.h"
class AutofillMetrics;
@@ -85,10 +86,8 @@ class WalletClientDelegate {
const std::string& instrument_id,
const std::vector<RequiredAction>& required_actions) = 0;
- // TODO(ahutter): This is going to need more arguments, probably an error
- // code and a message for the user.
// Called when a request fails due to an Online Wallet error.
- virtual void OnWalletError() = 0;
+ virtual void OnWalletError(WalletClient::ErrorType error_type) = 0;
// Called when a request fails due to a malformed response.
virtual void OnMalformedResponse() = 0;
diff --git a/components/autofill/browser/wallet/wallet_client_unittest.cc b/components/autofill/browser/wallet/wallet_client_unittest.cc
index b82ae8e..425a7db 100644
--- a/components/autofill/browser/wallet/wallet_client_unittest.cc
+++ b/components/autofill/browser/wallet/wallet_client_unittest.cc
@@ -225,6 +225,43 @@ const char kAuthenticateInstrumentSuccessResponse[] =
" \"auth_result\":\"SUCCESS\""
"}";
+const char kErrorResponse[] =
+ "{"
+ " \"error_type\":\"APPLICATION_ERROR\","
+ " \"error_detail\":\"error_detail\","
+ " \"application_error\":\"application_error\","
+ " \"debug_data\":"
+ " {"
+ " \"debug_message\":\"debug_message\","
+ " \"stack_trace\":\"stack_trace\""
+ " },"
+ " \"application_error_data\":\"application_error_data\","
+ " \"wallet_error\":"
+ " {"
+ " \"error_type\":\"SERVICE_UNAVAILABLE\","
+ " \"error_detail\":\"error_detail\","
+ " \"message_for_user\":"
+ " {"
+ " \"text\":\"text\","
+ " \"subtext\":\"subtext\","
+ " \"details\":\"details\""
+ " }"
+ " }"
+ "}";
+
+const char kErrorTypeMissingInResponse[] =
+ "{"
+ " \"error_type\":\"Not APPLICATION_ERROR\","
+ " \"error_detail\":\"error_detail\","
+ " \"application_error\":\"application_error\","
+ " \"debug_data\":"
+ " {"
+ " \"debug_message\":\"debug_message\","
+ " \"stack_trace\":\"stack_trace\""
+ " },"
+ " \"application_error_data\":\"application_error_data\""
+ "}";
+
// The JSON below is used to test against the request payload being sent to
// Online Wallet. It's indented differently since JSONWriter creates compact
// JSON from DictionaryValues.
@@ -530,7 +567,7 @@ class MockWalletClientDelegate : public WalletClientDelegate {
MOCK_METHOD2(OnDidUpdateInstrument,
void(const std::string& instrument_id,
const std::vector<RequiredAction>& required_actions));
- MOCK_METHOD0(OnWalletError, void());
+ MOCK_METHOD1(OnWalletError, void(WalletClient::ErrorType error_type));
MOCK_METHOD0(OnMalformedResponse, void());
MOCK_METHOD1(OnNetworkError, void(int response_code));
@@ -556,39 +593,38 @@ class MockWalletClientDelegate : public WalletClientDelegate {
// TODO(ahutter): Implement API compatibility tests. See
// http://crbug.com/164465.
-// TODO(ahutter): Improve this when the error body is captured. See
-// http://crbug.com/164410.
-TEST_F(WalletClientTest, WalletErrorOnExpectedVoidResponse) {
+TEST_F(WalletClientTest, WalletError) {
MockWalletClientDelegate delegate;
- EXPECT_CALL(delegate, OnWalletError()).Times(1);
+ EXPECT_CALL(delegate, OnWalletError(
+ WalletClient::SERVICE_UNAVAILABLE)).Times(1);
net::TestURLFetcherFactory factory;
WalletClient wallet_client(profile_.GetRequestContext(), &delegate);
wallet_client.SendAutocheckoutStatus(autofill::SUCCESS,
GURL(kMerchantUrl),
- "");
- net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
- ASSERT_TRUE(fetcher);
- fetcher->set_response_code(net::HTTP_INTERNAL_SERVER_ERROR);
- fetcher->delegate()->OnURLFetchComplete(fetcher);
+ "google_transaction_id");
+ VerifyAndFinishRequest(factory,
+ net::HTTP_INTERNAL_SERVER_ERROR,
+ kSendAutocheckoutStatusOfSuccessValidRequest,
+ kErrorResponse);
}
-// TODO(ahutter): Improve this when the error body is captured. See
-// http://crbug.com/164410.
-TEST_F(WalletClientTest, WalletErrorOnExpectedResponse) {
+TEST_F(WalletClientTest, WalletErrorResponseMissing) {
MockWalletClientDelegate delegate;
- EXPECT_CALL(delegate, OnWalletError()).Times(1);
+ EXPECT_CALL(delegate, OnWalletError(
+ WalletClient::UNKNOWN_ERROR)).Times(1);
net::TestURLFetcherFactory factory;
WalletClient wallet_client(profile_.GetRequestContext(), &delegate);
- wallet_client.GetWalletItems(GURL(kMerchantUrl),
- std::vector<WalletClient::RiskCapability>());
- net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
- ASSERT_TRUE(fetcher);
- fetcher->set_response_code(net::HTTP_INTERNAL_SERVER_ERROR);
- fetcher->delegate()->OnURLFetchComplete(fetcher);
+ wallet_client.SendAutocheckoutStatus(autofill::SUCCESS,
+ GURL(kMerchantUrl),
+ "google_transaction_id");
+ VerifyAndFinishRequest(factory,
+ net::HTTP_INTERNAL_SERVER_ERROR,
+ kSendAutocheckoutStatusOfSuccessValidRequest,
+ kErrorTypeMissingInResponse);
}
TEST_F(WalletClientTest, NetworkFailureOnExpectedVoidResponse) {
@@ -624,7 +660,7 @@ TEST_F(WalletClientTest, NetworkFailureOnExpectedResponse) {
TEST_F(WalletClientTest, RequestError) {
MockWalletClientDelegate delegate;
- EXPECT_CALL(delegate, OnWalletError()).Times(1);
+ EXPECT_CALL(delegate, OnWalletError(WalletClient::BAD_REQUEST)).Times(1);
net::TestURLFetcherFactory factory;
@@ -1523,11 +1559,12 @@ TEST_F(WalletClientTest, PendingRequest) {
kGetWalletItemsValidResponse);
EXPECT_EQ(0U, wallet_client.pending_requests_.size());
- EXPECT_CALL(delegate, OnWalletError()).Times(1);
+ EXPECT_CALL(delegate, OnWalletError(
+ WalletClient::SERVICE_UNAVAILABLE)).Times(1);
VerifyAndFinishRequest(factory,
net::HTTP_INTERNAL_SERVER_ERROR,
kGetWalletItemsValidRequest,
- std::string());
+ kErrorResponse);
}
TEST_F(WalletClientTest, CancelPendingRequests) {