diff options
author | ahutter@chromium.org <ahutter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-16 05:15:18 +0000 |
---|---|---|
committer | ahutter@chromium.org <ahutter@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-16 05:15:18 +0000 |
commit | 56cb9ea4d5c4d3058cdc22622f1de5c28682f615 (patch) | |
tree | e4042547c9eedefae51f1587a399b340f99b103c /components/autofill/browser | |
parent | 125abb32ec2957e070e5c6315b52a1697580b7ed (diff) | |
download | chromium_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/browser')
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) { |