diff options
author | zea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 23:24:04 +0000 |
---|---|---|
committer | zea@chromium.org <zea@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-02 23:24:04 +0000 |
commit | 651da6252ac3c36ec5d85b338f1fb0df16e940f4 (patch) | |
tree | f6e0920e4ae4dfbd3df67d557cf0d228e168c030 | |
parent | 67825502bb43b8549b4d50e5ee414ec5be66db9c (diff) | |
download | chromium_src-651da6252ac3c36ec5d85b338f1fb0df16e940f4.zip chromium_src-651da6252ac3c36ec5d85b338f1fb0df16e940f4.tar.gz chromium_src-651da6252ac3c36ec5d85b338f1fb0df16e940f4.tar.bz2 |
[Sync] Add support for sync Persistence Errors
Persistence errors are those detected by the native model's transaction
version being newer than sync's. They currently have no effect beyond
a normal association error, but will eventually result in delayed
association after a sync update.
BUG=239828
TBR=atwilson@chromium.org, sky@chromium.org
Review URL: https://chromiumcodereview.appspot.com/15701022
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@209810 0039d316-1c4b-4281-b951-d872f2087c98
45 files changed, 388 insertions, 177 deletions
diff --git a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc index 81537aa..b1b22a9 100644 --- a/chrome/browser/extensions/api/storage/settings_sync_unittest.cc +++ b/chrome/browser/extensions/api/storage/settings_sync_unittest.cc @@ -97,6 +97,7 @@ class MockSyncChangeProcessor : public syncer::SyncChangeProcessor { if (fail_all_requests_) { return syncer::SyncError( FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "MockSyncChangeProcessor: configured to fail", change_list[0].sync_data().GetDataType()); } diff --git a/chrome/browser/extensions/api/storage/syncable_settings_storage.cc b/chrome/browser/extensions/api/storage/syncable_settings_storage.cc index 5bfc039..66fd94f 100644 --- a/chrome/browser/extensions/api/storage/syncable_settings_storage.cc +++ b/chrome/browser/extensions/api/storage/syncable_settings_storage.cc @@ -141,6 +141,7 @@ syncer::SyncError SyncableSettingsStorage::StartSyncing( if (maybe_settings->HasError()) { return syncer::SyncError( FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, std::string("Failed to get settings: ") + maybe_settings->error(), sync_processor_->type()); } @@ -240,6 +241,7 @@ syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges( if (!sync_processor_.get()) { return syncer::SyncError( FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, std::string("Sync is inactive for ") + extension_id_, syncer::UNSPECIFIED); } @@ -260,6 +262,7 @@ syncer::SyncError SyncableSettingsStorage::ProcessSyncChanges( if (maybe_settings->HasError()) { errors.push_back(syncer::SyncError( FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, std::string("Error getting current sync state for ") + extension_id_ + "/" + key + ": " + maybe_settings->error(), sync_processor_->type())); @@ -339,6 +342,7 @@ syncer::SyncError SyncableSettingsStorage::OnSyncAdd( if (result->HasError()) { return syncer::SyncError( FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, std::string("Error pushing sync add to local settings: ") + result->error(), sync_processor_->type()); @@ -358,6 +362,7 @@ syncer::SyncError SyncableSettingsStorage::OnSyncUpdate( if (result->HasError()) { return syncer::SyncError( FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, std::string("Error pushing sync update to local settings: ") + result->error(), sync_processor_->type()); @@ -375,6 +380,7 @@ syncer::SyncError SyncableSettingsStorage::OnSyncDelete( if (result->HasError()) { return syncer::SyncError( FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, std::string("Error pushing sync remove to local settings: ") + result->error(), sync_processor_->type()); diff --git a/chrome/browser/history/delete_directive_handler.cc b/chrome/browser/history/delete_directive_handler.cc index 16ed55b..c08bf77 100644 --- a/chrome/browser/history/delete_directive_handler.cc +++ b/chrome/browser/history/delete_directive_handler.cc @@ -344,6 +344,7 @@ syncer::SyncError DeleteDirectiveHandler::ProcessLocalDeleteDirective( if (!sync_processor_) { return syncer::SyncError( FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Cannot send local delete directive to sync", syncer::HISTORY_DELETE_DIRECTIVES); } @@ -372,7 +373,10 @@ syncer::SyncError DeleteDirectiveHandler::ProcessSyncChanges( DCHECK(thread_checker_.CalledOnValidThread()); if (!sync_processor_) { return syncer::SyncError( - FROM_HERE, "Sync is disabled.", syncer::HISTORY_DELETE_DIRECTIVES); + FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Sync is disabled.", + syncer::HISTORY_DELETE_DIRECTIVES); } syncer::SyncDataList delete_directives; diff --git a/chrome/browser/history/typed_url_syncable_service.cc b/chrome/browser/history/typed_url_syncable_service.cc index 3b6d57e..fcb3cfa 100644 --- a/chrome/browser/history/typed_url_syncable_service.cc +++ b/chrome/browser/history/typed_url_syncable_service.cc @@ -119,6 +119,7 @@ syncer::SyncError TypedUrlSyncableService::ProcessSyncChanges( // TODO(mgist): Add implementation return syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Typed url syncable service is not implemented.", syncer::TYPED_URLS); } diff --git a/chrome/browser/policy/managed_mode_policy_provider_unittest.cc b/chrome/browser/policy/managed_mode_policy_provider_unittest.cc index 685f3ff..5b0d661 100644 --- a/chrome/browser/policy/managed_mode_policy_provider_unittest.cc +++ b/chrome/browser/policy/managed_mode_policy_provider_unittest.cc @@ -67,7 +67,10 @@ MockSyncErrorFactory::~MockSyncErrorFactory() {} syncer::SyncError MockSyncErrorFactory::CreateAndUploadError( const tracked_objects::Location& location, const std::string& message) { - return syncer::SyncError(location, message, type_); + return syncer::SyncError(location, + syncer::SyncError::DATATYPE_ERROR, + message, + type_); } class TestHarness : public PolicyProviderTestHarness { diff --git a/chrome/browser/prefs/pref_model_associator.cc b/chrome/browser/prefs/pref_model_associator.cc index c49f10c..07792cb 100644 --- a/chrome/browser/prefs/pref_model_associator.cc +++ b/chrome/browser/prefs/pref_model_associator.cc @@ -348,8 +348,9 @@ syncer::SyncError PrefModelAssociator::ProcessSyncChanges( const syncer::SyncChangeList& change_list) { if (!models_associated_) { syncer::SyncError error(FROM_HERE, - "Models not yet associated.", - PREFERENCES); + syncer::SyncError::DATATYPE_ERROR, + "Models not yet associated.", + PREFERENCES); return error; } base::AutoReset<bool> processing_changes(&processing_syncer_changes_, true); diff --git a/chrome/browser/search_engines/template_url_service.cc b/chrome/browser/search_engines/template_url_service.cc index bde41b0..b809632 100644 --- a/chrome/browser/search_engines/template_url_service.cc +++ b/chrome/browser/search_engines/template_url_service.cc @@ -890,8 +890,10 @@ syncer::SyncError TemplateURLService::ProcessSyncChanges( const tracked_objects::Location& from_here, const syncer::SyncChangeList& change_list) { if (!models_associated_) { - syncer::SyncError error(FROM_HERE, "Models not yet associated.", - syncer::SEARCH_ENGINES); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Models not yet associated.", + syncer::SEARCH_ENGINES); return error; } DCHECK(loaded_); diff --git a/chrome/browser/search_engines/template_url_service_sync_unittest.cc b/chrome/browser/search_engines/template_url_service_sync_unittest.cc index ccd2203..0e0c549 100644 --- a/chrome/browser/search_engines/template_url_service_sync_unittest.cc +++ b/chrome/browser/search_engines/template_url_service_sync_unittest.cc @@ -124,7 +124,10 @@ syncer::SyncError TestChangeProcessor::ProcessSyncChanges( const syncer::SyncChangeList& change_list) { if (erroneous_) return syncer::SyncError( - FROM_HERE, "Some error.", syncer::SEARCH_ENGINES); + FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Some error.", + syncer::SEARCH_ENGINES); change_map_.erase(change_map_.begin(), change_map_.end()); for (syncer::SyncChangeList::const_iterator iter = change_list.begin(); diff --git a/chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc b/chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc index d196f65..58c3d1b 100644 --- a/chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc +++ b/chrome/browser/spellchecker/spellcheck_custom_dictionary_unittest.cc @@ -154,7 +154,10 @@ class SyncErrorFactoryStub : public syncer::SyncErrorFactory { const tracked_objects::Location& location, const std::string& message) OVERRIDE { (*error_counter_)++; - return syncer::SyncError(location, message, syncer::DICTIONARY); + return syncer::SyncError(location, + syncer::SyncError::DATATYPE_ERROR, + message, + syncer::DICTIONARY); } private: diff --git a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc index 2703dbc0..e581409 100644 --- a/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/bookmark_data_type_controller_unittest.cc @@ -259,8 +259,9 @@ TEST_F(SyncBookmarkDataTypeControllerTest, StartAssociationFailed) { WillRepeatedly(DoAll(SetArgumentPointee<0>(true), Return(true))); EXPECT_CALL(*model_associator_, AssociateModels(_, _)). WillRepeatedly(Return(syncer::SyncError(FROM_HERE, - "error", - syncer::BOOKMARKS))); + syncer::SyncError::DATATYPE_ERROR, + "error", + syncer::BOOKMARKS))); EXPECT_CALL(start_callback_, Run(DataTypeController::ASSOCIATION_FAILED, _, _)); diff --git a/chrome/browser/sync/glue/bookmark_model_associator.cc b/chrome/browser/sync/glue/bookmark_model_associator.cc index 846d3e2..2782ec2 100644 --- a/chrome/browser/sync/glue/bookmark_model_associator.cc +++ b/chrome/browser/sync/glue/bookmark_model_associator.cc @@ -364,7 +364,10 @@ bool BookmarkModelAssociator::GetSyncIdForTaggedNode(const std::string& tag, syncer::SyncError BookmarkModelAssociator::AssociateModels( syncer::SyncMergeResult* local_merge_result, syncer::SyncMergeResult* syncer_merge_result) { - CheckModelSyncState(local_merge_result, syncer_merge_result); + syncer::SyncError error = CheckModelSyncState(local_merge_result, + syncer_merge_result); + if (error.IsSet()) + return error; scoped_ptr<ScopedAssociationUpdater> association_updater( new ScopedAssociationUpdater(bookmark_model_)); @@ -702,16 +705,16 @@ bool BookmarkModelAssociator::CryptoReadyIfNecessary() { trans.GetCryptographer()->is_ready(); } -void BookmarkModelAssociator::CheckModelSyncState( +syncer::SyncError BookmarkModelAssociator::CheckModelSyncState( syncer::SyncMergeResult* local_merge_result, syncer::SyncMergeResult* syncer_merge_result) const { std::string version_str; if (bookmark_model_->root_node()->GetMetaInfo(kBookmarkTransactionVersionKey, &version_str)) { syncer::ReadTransaction trans(FROM_HERE, user_share_); - int64 native_version; + int64 native_version = syncer::syncable::kInvalidTransactionVersion; if (!base::StringToInt64(version_str, &native_version)) - return; + return syncer::SyncError(); local_merge_result->set_pre_association_version(native_version); int64 sync_version = trans.GetModelVersion(syncer::BOOKMARKS); @@ -721,11 +724,21 @@ void BookmarkModelAssociator::CheckModelSyncState( UMA_HISTOGRAM_ENUMERATION("Sync.LocalModelOutOfSync", ModelTypeToHistogramInt(syncer::BOOKMARKS), syncer::MODEL_TYPE_COUNT); + // Clear version on bookmark model so that we only report error once. bookmark_model_->DeleteNodeMetaInfo(bookmark_model_->root_node(), kBookmarkTransactionVersionKey); + + // If the native version is higher, there was a sync persistence failure, + // and we need to delay association until after a GetUpdates. + if (sync_version < native_version) { + DVLOG(1) << "Native version (" << native_version << ") does not match " + << "sync version (" << sync_version << ")."; + // TODO(zea): return a persistence error here. + } } } + return syncer::SyncError(); } } // namespace browser_sync diff --git a/chrome/browser/sync/glue/bookmark_model_associator.h b/chrome/browser/sync/glue/bookmark_model_associator.h index 8a0ff5f..cf348b7 100644 --- a/chrome/browser/sync/glue/bookmark_model_associator.h +++ b/chrome/browser/sync/glue/bookmark_model_associator.h @@ -141,8 +141,11 @@ class BookmarkModelAssociator // Check whether bookmark model and sync model are synced by comparing // their transaction versions. - void CheckModelSyncState(syncer::SyncMergeResult* local_merge_result, - syncer::SyncMergeResult* syncer_merge_result) const; + // Returns a PERSISTENCE_ERROR if a transaction mismatch was detected where + // the native model has a newer transaction verison. + syncer::SyncError CheckModelSyncState( + syncer::SyncMergeResult* local_merge_result, + syncer::SyncMergeResult* syncer_merge_result) const; BookmarkModel* bookmark_model_; Profile* profile_; diff --git a/chrome/browser/sync/glue/data_type_controller.cc b/chrome/browser/sync/glue/data_type_controller.cc index 71095ab..cb56478 100644 --- a/chrome/browser/sync/glue/data_type_controller.cc +++ b/chrome/browser/sync/glue/data_type_controller.cc @@ -23,7 +23,10 @@ syncer::SyncError DataTypeController::CreateAndUploadError( const std::string& message, syncer::ModelType type) { ChromeReportUnrecoverableError(); - return syncer::SyncError(location, message, type); + return syncer::SyncError(location, + syncer::SyncError::DATATYPE_ERROR, + message, + type); } void DataTypeController::RecordUnrecoverableError( diff --git a/chrome/browser/sync/glue/data_type_manager_impl.cc b/chrome/browser/sync/glue/data_type_manager_impl.cc index 01f8fcb..7bcfd43 100644 --- a/chrome/browser/sync/glue/data_type_manager_impl.cc +++ b/chrome/browser/sync/glue/data_type_manager_impl.cc @@ -35,9 +35,11 @@ GenerateCryptoErrorsForTypes(syncer::ModelTypeSet encrypted_types) { FailedDataTypesHandler::TypeErrorMap crypto_errors; for (syncer::ModelTypeSet::Iterator iter = encrypted_types.First(); iter.Good(); iter.Inc()) { - crypto_errors[iter.Get()] = syncer::SyncError(FROM_HERE, - "Cryptographer not ready.", - iter.Get()); + crypto_errors[iter.Get()] = syncer::SyncError( + FROM_HERE, + syncer::SyncError::CRYPTO_ERROR, + "", + iter.Get()); } return crypto_errors; } @@ -187,9 +189,7 @@ void DataTypeManagerImpl::Restart(syncer::ConfigureReason reason) { failed_data_types_handler_->GetCryptoErrorTypes()); FailedDataTypesHandler::TypeErrorMap crypto_errors = GenerateCryptoErrorsForTypes(encrypted_types); - failed_data_types_handler_->UpdateFailedDataTypes( - crypto_errors, - FailedDataTypesHandler::CRYPTO); + failed_data_types_handler_->UpdateFailedDataTypes(crypto_errors); } else { failed_data_types_handler_->ResetCryptoErrors(); } @@ -298,7 +298,9 @@ void DataTypeManagerImpl::DownloadReady( std::string error_msg = "Configuration failed for types " + syncer::ModelTypeSetToString(failed_configuration_types); - syncer::SyncError error(FROM_HERE, error_msg, + syncer::SyncError error(FROM_HERE, + syncer::SyncError::UNRECOVERABLE_ERROR, + error_msg, failed_configuration_types.First().Get()); Abort(UNRECOVERABLE_ERROR, error); return; @@ -394,15 +396,12 @@ void DataTypeManagerImpl::OnModelAssociationDone( failed_data_types_handler_->GetCryptoErrorTypes()); FailedDataTypesHandler::TypeErrorMap crypto_errors = GenerateCryptoErrorsForTypes(encrypted_types); - failed_data_types_handler_->UpdateFailedDataTypes( - crypto_errors, - FailedDataTypesHandler::CRYPTO); + failed_data_types_handler_->UpdateFailedDataTypes(crypto_errors); } if (!result.failed_data_types.empty()) { needs_reconfigure_ = true; failed_data_types_handler_->UpdateFailedDataTypes( - result.failed_data_types, - FailedDataTypesHandler::STARTUP); + result.failed_data_types); } } @@ -489,7 +488,7 @@ void DataTypeManagerImpl::Abort(ConfigureStatus status, DCHECK_NE(OK, status); std::map<syncer::ModelType, syncer::SyncError> errors; if (error.IsSet()) - errors[error.type()] = error; + errors[error.model_type()] = error; ConfigureResult result(status, last_requested_types_, errors, diff --git a/chrome/browser/sync/glue/failed_data_types_handler.cc b/chrome/browser/sync/glue/failed_data_types_handler.cc index 594911f..01a3214 100644 --- a/chrome/browser/sync/glue/failed_data_types_handler.cc +++ b/chrome/browser/sync/glue/failed_data_types_handler.cc @@ -30,40 +30,53 @@ FailedDataTypesHandler::FailedDataTypesHandler() { FailedDataTypesHandler::~FailedDataTypesHandler() { } -bool FailedDataTypesHandler::UpdateFailedDataTypes( - const TypeErrorMap& errors, - FailureType failure_type) { - if (failure_type == RUNTIME) { - runtime_errors_.insert(errors.begin(), errors.end()); - } else if (failure_type == STARTUP) { - startup_errors_.insert(errors.begin(), errors.end()); - } else if (failure_type == CRYPTO) { - crypto_errors_.insert(errors.begin(), errors.end()); - } else { - NOTREACHED(); +bool FailedDataTypesHandler::UpdateFailedDataTypes(const TypeErrorMap& errors) { + if (errors.empty()) + return false; + + for (TypeErrorMap::const_iterator iter = errors.begin(); iter != errors.end(); + ++iter) { + syncer::SyncError::ErrorType failure_type = iter->second.error_type(); + switch (failure_type) { + case syncer::SyncError::UNRECOVERABLE_ERROR: + case syncer::SyncError::DATATYPE_ERROR: + fatal_errors_.insert(*iter); + break; + case syncer::SyncError::CRYPTO_ERROR: + crypto_errors_.insert(*iter); + break; + case syncer::SyncError::PERSISTENCE_ERROR: + persistence_errors_.insert(*iter); + break; + default: + NOTREACHED(); + } } - - return !errors.empty(); + return true; } void FailedDataTypesHandler::Reset() { - startup_errors_.clear(); - runtime_errors_.clear(); + fatal_errors_.clear(); crypto_errors_.clear(); + persistence_errors_.clear(); } void FailedDataTypesHandler::ResetCryptoErrors() { crypto_errors_.clear(); } +void FailedDataTypesHandler::ResetPersistenceErrors() { + persistence_errors_.clear(); +} + FailedDataTypesHandler::TypeErrorMap FailedDataTypesHandler::GetAllErrors() const { TypeErrorMap result; if (AnyFailedDataType()) { - result = startup_errors_; - result.insert(runtime_errors_.begin(), runtime_errors_.end()); + result = fatal_errors_; result.insert(crypto_errors_.begin(), crypto_errors_.end()); + result.insert(persistence_errors_.begin(), persistence_errors_.end()); } return result; } @@ -75,9 +88,7 @@ syncer::ModelTypeSet FailedDataTypesHandler::GetFailedTypes() const { } syncer::ModelTypeSet FailedDataTypesHandler::GetFatalErrorTypes() const { - syncer::ModelTypeSet result = GetTypesFromErrorMap(startup_errors_); - result.PutAll(GetTypesFromErrorMap(runtime_errors_)); - return result; + return GetTypesFromErrorMap(fatal_errors_);; } syncer::ModelTypeSet FailedDataTypesHandler::GetCryptoErrorTypes() const { @@ -85,9 +96,15 @@ syncer::ModelTypeSet FailedDataTypesHandler::GetCryptoErrorTypes() const { return result; } +syncer::ModelTypeSet FailedDataTypesHandler::GetPersistenceErrorTypes() const { + syncer::ModelTypeSet result = GetTypesFromErrorMap(persistence_errors_); + return result; +} + bool FailedDataTypesHandler::AnyFailedDataType() const { - return (!startup_errors_.empty() || !runtime_errors_.empty() || - !crypto_errors_.empty()); + // Note: persistence errors are not failed types. They just trigger automatic + // unapply + getupdates, at which point they are associated like normal. + return !fatal_errors_.empty() || !crypto_errors_.empty(); } } // namespace browser_sync diff --git a/chrome/browser/sync/glue/failed_data_types_handler.h b/chrome/browser/sync/glue/failed_data_types_handler.h index 1998cd8..3d8b211 100644 --- a/chrome/browser/sync/glue/failed_data_types_handler.h +++ b/chrome/browser/sync/glue/failed_data_types_handler.h @@ -14,25 +14,14 @@ namespace browser_sync { // Class to keep track of data types that have encountered an error during sync. class FailedDataTypesHandler { public: - enum FailureType { - // The dataype failed at startup. - STARTUP, - - // The datatype encountered a runtime error. - RUNTIME, - - // The datatype encountered a cryptographer related error. - CRYPTO - }; typedef std::map<syncer::ModelType, syncer::SyncError> TypeErrorMap; explicit FailedDataTypesHandler(); ~FailedDataTypesHandler(); - // Called with the result of sync configuration. The types with errors - // are obtained from the |result|. - bool UpdateFailedDataTypes(const TypeErrorMap& errors, - FailureType failure_type); + // Update the failed datatypes. Types will be added to their corresponding + // error map based on their |error_type()|. + bool UpdateFailedDataTypes(const TypeErrorMap& errors); // Resets the current set of data type errors. void Reset(); @@ -40,6 +29,9 @@ class FailedDataTypesHandler { // Resets the set of types with cryptographer errors. void ResetCryptoErrors(); + // Resets the set of types with persistence errors. + void ResetPersistenceErrors(); + // Returns a list of all the errors this class has recorded. TypeErrorMap GetAllErrors() const; @@ -52,19 +44,24 @@ class FailedDataTypesHandler { // Returns the types that are failing due to cryptographer errors. syncer::ModelTypeSet GetCryptoErrorTypes() const; + // Returns the types that are failing due to persistence errors. + syncer::ModelTypeSet GetPersistenceErrorTypes() const; + private: // Returns true if there are any types with errors. bool AnyFailedDataType() const; - // List of data types that failed at startup due to association errors. - TypeErrorMap startup_errors_; - - // List of data types that failed at runtime. - TypeErrorMap runtime_errors_; + // List of data types that failed at startup due to association errors or + // runtime due to data type errors. + TypeErrorMap fatal_errors_; // List of data types that failed due to the cryptographer not being ready. TypeErrorMap crypto_errors_; + // List of data type that failed because sync did not persist the newest + // version of their data. + TypeErrorMap persistence_errors_; + DISALLOW_COPY_AND_ASSIGN(FailedDataTypesHandler); }; diff --git a/chrome/browser/sync/glue/fake_data_type_controller.cc b/chrome/browser/sync/glue/fake_data_type_controller.cc index d424a1a..f21f27b 100644 --- a/chrome/browser/sync/glue/fake_data_type_controller.cc +++ b/chrome/browser/sync/glue/fake_data_type_controller.cc @@ -64,11 +64,17 @@ void FakeDataTypeController::FinishStart(StartResult result) { } else if (result == ASSOCIATION_FAILED) { state_ = DISABLED; local_merge_result.set_error( - syncer::SyncError(FROM_HERE, "Association failed", type())); + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Association failed", + type())); } else { state_ = NOT_RUNNING; local_merge_result.set_error( - syncer::SyncError(FROM_HERE, "Fake error", type())); + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Fake error", + type())); } StartCallback start_callback = last_start_callback_; last_start_callback_.Reset(); @@ -89,7 +95,10 @@ void FakeDataTypeController::Stop() { // The DTM still expects |last_start_callback_| to be called back. if (!last_start_callback_.is_null()) { - syncer::SyncError error(FROM_HERE, "Fake error", type_); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Fake error", + type_); syncer::SyncMergeResult local_merge_result(type_); local_merge_result.set_error(error); last_start_callback_.Run(ABORTED, diff --git a/chrome/browser/sync/glue/favicon_cache.cc b/chrome/browser/sync/glue/favicon_cache.cc index 4111f32..58416fc 100644 --- a/chrome/browser/sync/glue/favicon_cache.cc +++ b/chrome/browser/sync/glue/favicon_cache.cc @@ -326,6 +326,7 @@ syncer::SyncError FaviconCache::ProcessSyncChanges( if (!favicon_images_sync_processor_.get() || !favicon_tracking_sync_processor_.get()) { return syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "One or both favicon types disabled.", change_list[0].sync_data().GetDataType()); } diff --git a/chrome/browser/sync/glue/favicon_cache_unittest.cc b/chrome/browser/sync/glue/favicon_cache_unittest.cc index cde093c..697f371 100644 --- a/chrome/browser/sync/glue/favicon_cache_unittest.cc +++ b/chrome/browser/sync/glue/favicon_cache_unittest.cc @@ -77,7 +77,10 @@ syncer::SyncError TestChangeProcessor::ProcessSyncChanges( const syncer::SyncChangeList& change_list) { if (erroneous_) { return syncer::SyncError( - FROM_HERE, "Some error.", change_list[0].sync_data().GetDataType()); + FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Some error.", + change_list[0].sync_data().GetDataType()); } change_list_.insert(change_list_.end(), diff --git a/chrome/browser/sync/glue/frontend_data_type_controller.cc b/chrome/browser/sync/glue/frontend_data_type_controller.cc index c3b0cf6..043ca23 100644 --- a/chrome/browser/sync/glue/frontend_data_type_controller.cc +++ b/chrome/browser/sync/glue/frontend_data_type_controller.cc @@ -40,7 +40,9 @@ void FrontendDataTypeController::LoadModels( DCHECK(!model_load_callback.is_null()); if (state_ != NOT_RUNNING) { - model_load_callback.Run(type(), syncer::SyncError(FROM_HERE, + model_load_callback.Run(type(), + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Model already running", type())); return; @@ -170,7 +172,10 @@ bool FrontendDataTypeController::Associate() { bool sync_has_nodes = false; if (!model_associator()->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - syncer::SyncError error(FROM_HERE, "Failed to load sync nodes", type()); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::UNRECOVERABLE_ERROR, + "Failed to load sync nodes", + type()); local_merge_result.set_error(error); StartDone(UNRECOVERABLE_ERROR, local_merge_result, syncer_merge_result); return false; @@ -223,7 +228,9 @@ void FrontendDataTypeController::AbortModelLoad() { state_ = NOT_RUNNING; ModelLoadCallback model_load_callback = model_load_callback_; model_load_callback_.Reset(); - model_load_callback.Run(type(), syncer::SyncError(FROM_HERE, + model_load_callback.Run(type(), + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Aborted", type())); } diff --git a/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc b/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc index c9422a3..12c1923 100644 --- a/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/frontend_data_type_controller_unittest.cc @@ -209,8 +209,9 @@ TEST_F(SyncFrontendDataTypeControllerTest, StartAssociationFailed) { WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); EXPECT_CALL(*model_associator_, AssociateModels(_, _)). WillOnce(Return(syncer::SyncError(FROM_HERE, - "error", - syncer::BOOKMARKS))); + syncer::SyncError::DATATYPE_ERROR, + "error", + syncer::BOOKMARKS))); EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED); diff --git a/chrome/browser/sync/glue/generic_change_processor.cc b/chrome/browser/sync/glue/generic_change_processor.cc index cf1daa8..591e717 100644 --- a/chrome/browser/sync/glue/generic_change_processor.cc +++ b/chrome/browser/sync/glue/generic_change_processor.cc @@ -83,7 +83,10 @@ void GenericChangeProcessor::CommitChangesFromSyncModel() { return; if (!local_service_.get()) { syncer::ModelType type = syncer_changes_[0].sync_data().GetDataType(); - syncer::SyncError error(FROM_HERE, "Local service destroyed.", type); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Local service destroyed.", + type); error_handler()->OnSingleDatatypeUnrecoverableError(error.location(), error.message()); return; @@ -107,9 +110,11 @@ syncer::SyncError GenericChangeProcessor::GetSyncDataForType( if (root.InitByTagLookup(syncer::ModelTypeToRootTag(type)) != syncer::BaseNode::INIT_OK) { syncer::SyncError error(FROM_HERE, - "Server did not create the top-level " + type_name + - " node. We might be running against an out-of-date server.", - type); + syncer::SyncError::DATATYPE_ERROR, + "Server did not create the top-level " + type_name + + " node. We might be running against an out-of-" + "date server.", + type); return error; } @@ -125,8 +130,10 @@ syncer::SyncError GenericChangeProcessor::GetSyncDataForType( if (sync_child_node.InitByIdLookup(*it) != syncer::BaseNode::INIT_OK) { syncer::SyncError error(FROM_HERE, - "Failed to fetch child node for type " + type_name + ".", - type); + syncer::SyncError::DATATYPE_ERROR, + "Failed to fetch child node for type " + + type_name + ".", + type); return error; } current_sync_data->push_back(syncer::SyncData::CreateRemoteData( @@ -221,6 +228,7 @@ syncer::SyncError AttemptDelete( if (tag.empty()) { syncer::SyncError error( FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Failed to delete " + type_str + " node. Local data, empty tag. " + change.location().ToString(), type); @@ -297,8 +305,10 @@ syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( syncer::ModelTypeToRootTag(change.sync_data().GetDataType())) != syncer::BaseNode::INIT_OK) { syncer::SyncError error(FROM_HERE, - "Failed to look up root node for type " + type_str, - type); + syncer::SyncError::DATATYPE_ERROR, + "Failed to look up root node for type " + + type_str, + type); error_handler()->OnSingleDatatypeUnrecoverableError(FROM_HERE, error.message()); NOTREACHED(); @@ -461,6 +471,7 @@ syncer::SyncError GenericChangeProcessor::ProcessSyncChanges( } else { syncer::SyncError error( FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Received unset SyncChange in the change processor, " + change.location().ToString(), type); diff --git a/chrome/browser/sync/glue/model_association_manager.cc b/chrome/browser/sync/glue/model_association_manager.cc index 4049523..e17a145 100644 --- a/chrome/browser/sync/glue/model_association_manager.cc +++ b/chrome/browser/sync/glue/model_association_manager.cc @@ -311,11 +311,11 @@ bool ModelAssociationManager::GetControllersNeedingStart( void ModelAssociationManager::AppendToFailedDatatypesAndLogError( DataTypeController::StartResult result, const syncer::SyncError& error) { - failed_data_types_info_[error.type()] = error; + failed_data_types_info_[error.model_type()] = error; LOG(ERROR) << "Failed to associate models for " - << syncer::ModelTypeToString(error.type()); + << syncer::ModelTypeToString(error.model_type()); UMA_HISTOGRAM_ENUMERATION("Sync.ConfigureFailed", - ModelTypeToHistogramInt(error.type()), + ModelTypeToHistogramInt(error.model_type()), syncer::MODEL_TYPE_COUNT); } @@ -386,7 +386,7 @@ void ModelAssociationManager::TypeStartCallback( // Any other result requires reconfiguration. Pass it on through the callback. LOG(ERROR) << "Failed to configure " << started_dtc->name(); DCHECK(local_merge_result.error().IsSet()); - DCHECK_EQ(started_dtc->type(), local_merge_result.error().type()); + DCHECK_EQ(started_dtc->type(), local_merge_result.error().model_type()); DataTypeManager::ConfigureStatus configure_status = DataTypeManager::ABORTED; switch (start_result) { diff --git a/chrome/browser/sync/glue/model_association_manager_unittest.cc b/chrome/browser/sync/glue/model_association_manager_unittest.cc index a36596f..46b64fa 100644 --- a/chrome/browser/sync/glue/model_association_manager_unittest.cc +++ b/chrome/browser/sync/glue/model_association_manager_unittest.cc @@ -171,7 +171,10 @@ TEST_F(SyncModelAssociationManagerTest, TypeFailModelAssociation) { syncer::ModelTypeSet types; types.Put(syncer::BOOKMARKS); std::map<syncer::ModelType, syncer::SyncError> errors; - syncer::SyncError error(FROM_HERE, "Failed", syncer::BOOKMARKS); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Failed", + syncer::BOOKMARKS); errors[syncer::BOOKMARKS] = error; DataTypeManager::ConfigureResult expected_result( DataTypeManager::PARTIAL_SUCCESS, @@ -202,7 +205,10 @@ TEST_F(SyncModelAssociationManagerTest, TypeReturnUnrecoverableError) { syncer::ModelTypeSet types; types.Put(syncer::BOOKMARKS); std::map<syncer::ModelType, syncer::SyncError> errors; - syncer::SyncError error(FROM_HERE, "Failed", syncer::BOOKMARKS); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Failed", + syncer::BOOKMARKS); errors[syncer::BOOKMARKS] = error; DataTypeManager::ConfigureResult expected_result( DataTypeManager::UNRECOVERABLE_ERROR, diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc index 1ff03e4..56a07f3 100644 --- a/chrome/browser/sync/glue/non_frontend_data_type_controller.cc +++ b/chrome/browser/sync/glue/non_frontend_data_type_controller.cc @@ -48,7 +48,9 @@ void NonFrontendDataTypeController::LoadModels( start_association_called_.Reset(); start_models_failed_ = false; if (state_ != NOT_RUNNING) { - model_load_callback.Run(type(), syncer::SyncError(FROM_HERE, + model_load_callback.Run(type(), + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Model already loaded", type())); return; @@ -63,7 +65,9 @@ void NonFrontendDataTypeController::LoadModels( // get a false it means they failed. DCHECK(state_ == NOT_RUNNING || state_ == MODEL_STARTING || state_ == DISABLED); - model_load_callback.Run(type(), syncer::SyncError(FROM_HERE, + model_load_callback.Run(type(), + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Failed loading", type())); return; @@ -88,7 +92,9 @@ void NonFrontendDataTypeController::StartAssociating( start_callback_ = start_callback; if (!StartAssociationAsync()) { syncer::SyncError error( - FROM_HERE, "Failed to post StartAssociation", type()); + FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Failed to post StartAssociation", type()); syncer::SyncMergeResult local_merge_result(type()); local_merge_result.set_error(error); StartDoneImpl(ASSOCIATION_FAILED, @@ -418,7 +424,10 @@ void NonFrontendDataTypeController::StartAssociation() { bool sync_has_nodes = false; if (!model_associator_->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - syncer::SyncError error(FROM_HERE, "Failed to load sync nodes", type()); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::UNRECOVERABLE_ERROR, + "Failed to load sync nodes", + type()); local_merge_result.set_error(error); StartDone(UNRECOVERABLE_ERROR, local_merge_result, diff --git a/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc b/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc index fa64025..2c6a1d6 100644 --- a/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/non_frontend_data_type_controller_unittest.cc @@ -250,7 +250,10 @@ TEST_F(SyncNonFrontendDataTypeControllerTest, StartAssociationFailed) { WillOnce(DoAll(SetArgumentPointee<0>(true), Return(true))); EXPECT_CALL(*model_associator_, AssociateModels(_, _)). WillOnce( - Return(syncer::SyncError(FROM_HERE, "Error", syncer::BOOKMARKS))); + Return(syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Error", + syncer::BOOKMARKS))); EXPECT_CALL(*dtc_mock_.get(), RecordAssociationTime(_)); SetStartFailExpectations(DataTypeController::ASSOCIATION_FAILED); // Set up association to fail with an association failed error. diff --git a/chrome/browser/sync/glue/non_ui_data_type_controller.cc b/chrome/browser/sync/glue/non_ui_data_type_controller.cc index 6cb7516..48c3023 100644 --- a/chrome/browser/sync/glue/non_ui_data_type_controller.cc +++ b/chrome/browser/sync/glue/non_ui_data_type_controller.cc @@ -35,9 +35,11 @@ void NonUIDataTypeController::LoadModels( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(!model_load_callback.is_null()); if (state() != NOT_RUNNING) { - model_load_callback.Run(type(), syncer::SyncError(FROM_HERE, - "Model already running", - type())); + model_load_callback.Run(type(), + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Model already running", + type())); return; } @@ -92,7 +94,10 @@ void NonUIDataTypeController::StartAssociating( start_callback_ = start_callback; if (!StartAssociationAsync()) { syncer::SyncError error( - FROM_HERE, "Failed to post StartAssociation", type()); + FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Failed to post StartAssociation", + type()); syncer::SyncMergeResult local_merge_result(type()); local_merge_result.set_error(error); StartDoneImpl(ASSOCIATION_FAILED, @@ -273,9 +278,11 @@ void NonUIDataTypeController::AbortModelLoad() { StopModels(); ModelLoadCallback model_load_callback = model_load_callback_; model_load_callback_.Reset(); - model_load_callback.Run(type(), syncer::SyncError(FROM_HERE, - "ABORTED", - type())); + model_load_callback.Run(type(), + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "ABORTED", + type())); } void NonUIDataTypeController::DisableImpl( @@ -323,7 +330,10 @@ void NonUIDataTypeController:: type(), weak_ptr_factory.GetWeakPtr()); if (!local_service_.get()) { - syncer::SyncError error(FROM_HERE, "Failed to connect to syncer.", type()); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Failed to connect to syncer.", + type()); local_merge_result.set_error(error); StartDone(ASSOCIATION_FAILED, local_merge_result, @@ -340,7 +350,10 @@ void NonUIDataTypeController:: bool sync_has_nodes = false; if (!shared_change_processor->SyncModelHasUserCreatedNodes(&sync_has_nodes)) { - syncer::SyncError error(FROM_HERE, "Failed to load sync nodes", type()); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::UNRECOVERABLE_ERROR, + "Failed to load sync nodes", + type()); local_merge_result.set_error(error); StartDone(UNRECOVERABLE_ERROR, local_merge_result, @@ -418,4 +431,4 @@ void NonUIDataTypeController::StopLocalService() { local_service_.reset(); } -} // namepsace browser_sync +} // namespace browser_sync diff --git a/chrome/browser/sync/glue/non_ui_data_type_controller_unittest.cc b/chrome/browser/sync/glue/non_ui_data_type_controller_unittest.cc index 43107da..f546bf6 100644 --- a/chrome/browser/sync/glue/non_ui_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/non_ui_data_type_controller_unittest.cc @@ -323,7 +323,9 @@ TEST_F(SyncNonUIDataTypeControllerTest, StartAssociationFailed) { EXPECT_EQ(DataTypeController::NOT_RUNNING, non_ui_dtc_->state()); syncable_service_.set_merge_data_and_start_syncing_error( syncer::SyncError(FROM_HERE, - "Sync Error", non_ui_dtc_->type())); + syncer::SyncError::DATATYPE_ERROR, + "Sync Error", + non_ui_dtc_->type())); Start(); WaitForDTC(); EXPECT_EQ(DataTypeController::DISABLED, non_ui_dtc_->state()); @@ -381,7 +383,10 @@ TEST_F(SyncNonUIDataTypeControllerTest, AbortDuringAssociation) { SetArgumentPointee<0>(true), Return(true))); EXPECT_CALL(*change_processor_.get(), GetSyncData(_)).WillOnce( - Return(syncer::SyncError(FROM_HERE, "Disconnected.", AUTOFILL_PROFILE))); + Return(syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Disconnected.", + AUTOFILL_PROFILE))); EXPECT_CALL(*change_processor_.get(), Disconnect()) .WillOnce(DoAll(SignalEvent(&pause_db_thread), Return(true))); EXPECT_CALL(service_, DeactivateDataType(_)); diff --git a/chrome/browser/sync/glue/password_model_associator.cc b/chrome/browser/sync/glue/password_model_associator.cc index e2fcb7e..f034c47 100644 --- a/chrome/browser/sync/glue/password_model_associator.cc +++ b/chrome/browser/sync/glue/password_model_associator.cc @@ -71,6 +71,7 @@ syncer::SyncError PasswordModelAssociator::AssociateModels( ModelTypeToHistogramInt(syncer::PASSWORDS), syncer::MODEL_TYPE_COUNT); return syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Could not get the password entries.", model_type()); } diff --git a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc index 978c329..1e2a360 100644 --- a/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/search_engine_data_type_controller_unittest.cc @@ -164,7 +164,10 @@ TEST_F(SyncSearchEngineDataTypeControllerTest, StartAssociationFailed) { EXPECT_CALL(start_callback_, Run(DataTypeController::ASSOCIATION_FAILED, _, _)); syncable_service_.set_merge_data_and_start_syncing_error( - syncer::SyncError(FROM_HERE, "Error", syncer::SEARCH_ENGINES)); + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Error", + syncer::SEARCH_ENGINES)); Start(); EXPECT_EQ(DataTypeController::DISABLED, search_engine_dtc_->state()); diff --git a/chrome/browser/sync/glue/shared_change_processor.cc b/chrome/browser/sync/glue/shared_change_processor.cc index 0dd0833..abe7070 100644 --- a/chrome/browser/sync/glue/shared_change_processor.cc +++ b/chrome/browser/sync/glue/shared_change_processor.cc @@ -95,7 +95,10 @@ syncer::SyncError SharedChangeProcessor::GetSyncData( DCHECK(backend_loop_->BelongsToCurrentThread()); AutoLock lock(monitor_lock_); if (disconnected_) { - syncer::SyncError error(FROM_HERE, "Change processor disconnected.", type_); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Change processor disconnected.", + type_); return error; } return generic_change_processor_->GetSyncDataForType(type_, @@ -122,7 +125,10 @@ syncer::SyncError SharedChangeProcessor::ProcessSyncChanges( if (disconnected_) { // The DTC that disconnects us must ensure it posts a StopSyncing task. // If we reach this, it means it just hasn't executed yet. - syncer::SyncError error(FROM_HERE, "Change processor disconnected.", type_); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Change processor disconnected.", + type_); return error; } return generic_change_processor_->ProcessSyncChanges( @@ -173,7 +179,10 @@ syncer::SyncError SharedChangeProcessor::CreateAndUploadError( if (!disconnected_) { return error_handler_->CreateAndUploadError(location, message, type_); } else { - return syncer::SyncError(location, message, type_); + return syncer::SyncError(location, + syncer::SyncError::DATATYPE_ERROR, + message, + type_); } } diff --git a/chrome/browser/sync/glue/ui_data_type_controller.cc b/chrome/browser/sync/glue/ui_data_type_controller.cc index 830999e..1ed6b86 100644 --- a/chrome/browser/sync/glue/ui_data_type_controller.cc +++ b/chrome/browser/sync/glue/ui_data_type_controller.cc @@ -55,7 +55,9 @@ void UIDataTypeController::LoadModels( DCHECK(!model_load_callback.is_null()); DCHECK(syncer::IsRealDataType(type_)); if (state_ != NOT_RUNNING) { - model_load_callback.Run(type(), syncer::SyncError(FROM_HERE, + model_load_callback.Run(type(), + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Model already loaded", type())); return; @@ -131,7 +133,10 @@ void UIDataTypeController::Associate() { type(), weak_ptr_factory.GetWeakPtr()); if (!local_service_.get()) { - syncer::SyncError error(FROM_HERE, "Failed to connect to syncer.", type()); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Failed to connect to syncer.", + type()); local_merge_result.set_error(error); StartDone(ASSOCIATION_FAILED, local_merge_result, @@ -149,7 +154,10 @@ void UIDataTypeController::Associate() { bool sync_has_nodes = false; if (!shared_change_processor_->SyncModelHasUserCreatedNodes( &sync_has_nodes)) { - syncer::SyncError error(FROM_HERE, "Failed to load sync nodes", type()); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::UNRECOVERABLE_ERROR, + "Failed to load sync nodes", + type()); local_merge_result.set_error(error); StartDone(UNRECOVERABLE_ERROR, local_merge_result, @@ -207,7 +215,9 @@ void UIDataTypeController::AbortModelLoad() { ModelLoadCallback model_load_callback = model_load_callback_; model_load_callback_.Reset(); - model_load_callback.Run(type(), syncer::SyncError(FROM_HERE, + model_load_callback.Run(type(), + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Aborted", type())); } diff --git a/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc b/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc index ce64106..5edb108 100644 --- a/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc +++ b/chrome/browser/sync/glue/ui_data_type_controller_unittest.cc @@ -166,7 +166,10 @@ TEST_F(SyncUIDataTypeControllerTest, StartAssociationFailed) { EXPECT_CALL(start_callback_, Run(DataTypeController::ASSOCIATION_FAILED, _, _)); syncable_service_.set_merge_data_and_start_syncing_error( - syncer::SyncError(FROM_HERE, "Error", type_)); + syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Error", + type_)); EXPECT_EQ(DataTypeController::NOT_RUNNING, preference_dtc_->state()); EXPECT_FALSE(syncable_service_.syncing()); diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index 8a61a2e..26f26d1 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -860,16 +860,17 @@ void ProfileSyncService::DisableBrokenDatatype( // passed onto the change processor. DeactivateDataType(type); - syncer::SyncError error(from_here, message, type); + syncer::SyncError error(from_here, + syncer::SyncError::DATATYPE_ERROR, + message, + type); std::map<syncer::ModelType, syncer::SyncError> errors; errors[type] = error; // Update this before posting a task. So if a configure happens before // the task that we are going to post, this type would still be disabled. - failed_data_types_handler_.UpdateFailedDataTypes( - errors, - FailedDataTypesHandler::RUNTIME); + failed_data_types_handler_.UpdateFailedDataTypes(errors); base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(&ProfileSyncService::ReconfigureDatatypeManager, @@ -1277,7 +1278,7 @@ void ProfileSyncService::OnConfigureDone( std::string message = "Sync configuration failed with status " + DataTypeManager::ConfigureStatusToString(configure_status_) + - " during " + syncer::ModelTypeToString(error.type()) + + " during " + syncer::ModelTypeToString(error.model_type()) + ": " + error.message(); LOG(ERROR) << "ProfileSyncService error: " << message; OnInternalUnrecoverableError(error.location(), diff --git a/chrome/browser/sync/profile_sync_service_startup_unittest.cc b/chrome/browser/sync/profile_sync_service_startup_unittest.cc index be60db9..dc58aa8 100644 --- a/chrome/browser/sync/profile_sync_service_startup_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_startup_unittest.cc @@ -513,7 +513,10 @@ TEST_F(ProfileSyncServiceStartupTest, StartFailure) { DataTypeManagerMock* data_type_manager = SetUpDataTypeManager(); DataTypeManager::ConfigureStatus status = DataTypeManager::ABORTED; syncer::SyncError error( - FROM_HERE, "Association failed.", syncer::BOOKMARKS); + FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Association failed.", + syncer::BOOKMARKS); std::map<syncer::ModelType, syncer::SyncError> errors; errors[syncer::BOOKMARKS] = error; DataTypeManager::ConfigureResult result( diff --git a/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc b/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc index 862bb36..aedffb0 100644 --- a/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_typed_url_unittest.cc @@ -943,9 +943,11 @@ TEST_F(ProfileSyncServiceTypedUrlTest, FailToGetTypedURLs) { sync_entries.push_back(sync_entry); EXPECT_CALL(error_handler_, CreateAndUploadError(_, _, _)). - WillOnce(Return(syncer::SyncError(FROM_HERE, - "Unit test", - syncer::TYPED_URLS))); + WillOnce(Return(syncer::SyncError( + FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Unit test", + syncer::TYPED_URLS))); StartSyncService(base::Bind(&AddTypedUrlEntries, this, sync_entries)); // Errors getting typed URLs will cause an unrecoverable error (since we can // do *nothing* in that case). diff --git a/chrome/browser/themes/theme_syncable_service.cc b/chrome/browser/themes/theme_syncable_service.cc index bf414d6..3389443 100644 --- a/chrome/browser/themes/theme_syncable_service.cc +++ b/chrome/browser/themes/theme_syncable_service.cc @@ -135,6 +135,7 @@ syncer::SyncError ThemeSyncableService::ProcessSyncChanges( if (!sync_processor_.get()) { return syncer::SyncError(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, "Theme syncable service is not started.", syncer::THEMES); } @@ -180,8 +181,8 @@ syncer::SyncError ThemeSyncableService::ProcessSyncChanges( } return syncer::SyncError(FROM_HERE, - base::StringPrintf( - "Didn't find valid theme specifics."), + syncer::SyncError::DATATYPE_ERROR, + "Didn't find valid theme specifics", syncer::THEMES); } diff --git a/chrome/browser/themes/theme_syncable_service_unittest.cc b/chrome/browser/themes/theme_syncable_service_unittest.cc index 4099223..5931a17 100644 --- a/chrome/browser/themes/theme_syncable_service_unittest.cc +++ b/chrome/browser/themes/theme_syncable_service_unittest.cc @@ -505,8 +505,9 @@ TEST_F(ThemeSyncableServiceTest, StopSync) { // ProcessSyncChanges() should return error when sync has stopped. error = theme_sync_service_->ProcessSyncChanges(FROM_HERE, change_list); EXPECT_TRUE(error.IsSet()); - EXPECT_EQ(syncer::THEMES, error.type()); - EXPECT_EQ("Theme syncable service is not started.", + EXPECT_EQ(syncer::THEMES, error.model_type()); + EXPECT_EQ("datatype error was encountered: Theme syncable service is not " + "started.", error.message()); } diff --git a/chrome/browser/webdata/autocomplete_syncable_service.cc b/chrome/browser/webdata/autocomplete_syncable_service.cc index 15c6931..a57994a 100644 --- a/chrome/browser/webdata/autocomplete_syncable_service.cc +++ b/chrome/browser/webdata/autocomplete_syncable_service.cc @@ -238,8 +238,10 @@ syncer::SyncError AutocompleteSyncableService::ProcessSyncChanges( DCHECK(sync_processor_.get()); if (!sync_processor_.get()) { - syncer::SyncError error(FROM_HERE, "Models not yet associated.", - syncer::AUTOFILL); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Models not yet associated.", + syncer::AUTOFILL); return error; } diff --git a/chrome/browser/webdata/autofill_profile_syncable_service.cc b/chrome/browser/webdata/autofill_profile_syncable_service.cc index ba1a082..530f390 100644 --- a/chrome/browser/webdata/autofill_profile_syncable_service.cc +++ b/chrome/browser/webdata/autofill_profile_syncable_service.cc @@ -228,8 +228,10 @@ syncer::SyncError AutofillProfileSyncableService::ProcessSyncChanges( const syncer::SyncChangeList& change_list) { DCHECK(CalledOnValidThread()); if (!sync_processor_.get()) { - syncer::SyncError error(FROM_HERE, "Models not yet associated.", - syncer::AUTOFILL_PROFILE); + syncer::SyncError error(FROM_HERE, + syncer::SyncError::DATATYPE_ERROR, + "Models not yet associated.", + syncer::AUTOFILL_PROFILE); return error; } diff --git a/sync/api/sync_error.cc b/sync/api/sync_error.cc index 1209040..ee6885c 100644 --- a/sync/api/sync_error.cc +++ b/sync/api/sync_error.cc @@ -17,9 +17,28 @@ SyncError::SyncError() { } SyncError::SyncError(const tracked_objects::Location& location, - const std::string& message, - ModelType type) { - Init(location, message, type); + ErrorType error_type, + const std::string& custom_message, + ModelType model_type) { + std::string type_message; + switch (error_type) { + case UNRECOVERABLE_ERROR: + type_message = "unrecoverable error was encountered: "; + break; + case DATATYPE_ERROR: + type_message = "datatype error was encountered: "; + break; + case PERSISTENCE_ERROR: + type_message = "persistence error was encountered: "; + break; + case CRYPTO_ERROR: + type_message = "cryptographer error was encountered: "; + break; + default: + NOTREACHED(); + type_message = "invalid error: "; + } + Init(location, type_message + custom_message, model_type, error_type); PrintLogError(); } @@ -42,7 +61,8 @@ void SyncError::Copy(const SyncError& other) { if (other.IsSet()) { Init(other.location(), other.message(), - other.type()); + other.model_type(), + other.error_type()); } else { Clear(); } @@ -51,26 +71,29 @@ void SyncError::Copy(const SyncError& other) { void SyncError::Clear() { location_.reset(); message_ = std::string(); - type_ = UNSPECIFIED; + model_type_ = UNSPECIFIED; + error_type_ = UNSET; } void SyncError::Reset(const tracked_objects::Location& location, const std::string& message, - ModelType type) { - Init(location, message, type); + ModelType model_type) { + Init(location, message, model_type, DATATYPE_ERROR); PrintLogError(); } void SyncError::Init(const tracked_objects::Location& location, const std::string& message, - ModelType type) { + ModelType model_type, + ErrorType error_type) { location_.reset(new tracked_objects::Location(location)); message_ = message; - type_ = type; + model_type_ = model_type; + error_type_ = error_type; } bool SyncError::IsSet() const { - return location_.get() != NULL; + return error_type_ != UNSET; } @@ -84,17 +107,22 @@ const std::string& SyncError::message() const { return message_; } -ModelType SyncError::type() const { +ModelType SyncError::model_type() const { + CHECK(IsSet()); + return model_type_; +} + +SyncError::ErrorType SyncError::error_type() const { CHECK(IsSet()); - return type_; + return error_type_; } std::string SyncError::ToString() const { if (!IsSet()) { return std::string(); } - return location_->ToString() + ", " + ModelTypeToString(type_) + - ", Sync Error: " + message_; + return location_->ToString() + ", " + ModelTypeToString(model_type_) + + " " + message_; } void SyncError::PrintLogError() const { @@ -102,7 +130,7 @@ void SyncError::PrintLogError() const { location_->line_number(), logging::LOG_ERROR).stream(), LOG_IS_ON(ERROR)) - << ModelTypeToString(type_) << ", Sync Error: " << message_; + << ModelTypeToString(model_type_) << " " << message_; } void PrintTo(const SyncError& sync_error, std::ostream* os) { diff --git a/sync/api/sync_error.h b/sync/api/sync_error.h index e9ca0f6..306ed83 100644 --- a/sync/api/sync_error.h +++ b/sync/api/sync_error.h @@ -19,21 +19,35 @@ class Location; namespace syncer { // Sync errors are used for debug purposes and handled internally and/or -// exposed through Chrome's "about:sync" internal page. They are considered -// unrecoverable for the datatype creating them, and should only be used as -// such. +// exposed through Chrome's "about:sync" internal page. // This class is copy-friendly and thread-safe. class SYNC_EXPORT SyncError { public: + // Error types are used to distinguish general datatype errors (which result + // in the datatype being disabled) from actionable sync errors (which might + // have more complicated results). + enum ErrorType { + UNSET, // No error. + UNRECOVERABLE_ERROR, // An unrecoverable runtime error was encountered, and + // sync should be disabled completely. + DATATYPE_ERROR, // A datatype error was encountered, and the datatype + // should be disabled. + PERSISTENCE_ERROR, // A persistence error was detected, and the + // datataype should be associated after a sync update. + CRYPTO_ERROR, // A cryptographer error was detected, and the + // datatype should be associated after it is resolved. + }; + // Default constructor refers to "no error", and IsSet() will return false. SyncError(); - // Create a new Sync error triggered by datatype |type| with debug message - // |message| from the specified location. IsSet() will return true. - // Will print the new error to LOG(ERROR). + // Create a new Sync error of type |error_type| triggered by |model_type| + // from the specified location. IsSet() will return true afterward. Will + // create and print an error specific message to LOG(ERROR). SyncError(const tracked_objects::Location& location, + ErrorType error_type, const std::string& message, - ModelType type); + ModelType model_type); // Copy and assign via deep copy. SyncError(const SyncError& other); @@ -41,8 +55,9 @@ class SYNC_EXPORT SyncError { ~SyncError(); - // Reset the current error to a new error. May be called irrespective of - // whether IsSet() is true. After this is called, IsSet() will return true. + // Reset the current error to a new datatype error. May be called + // irrespective of whether IsSet() is true. After this is called, IsSet() + // will return true. // Will print the new error to LOG(ERROR). void Reset(const tracked_objects::Location& location, const std::string& message, @@ -54,7 +69,8 @@ class SYNC_EXPORT SyncError { // These must only be called if IsSet() is true. const tracked_objects::Location& location() const; const std::string& message() const; - ModelType type() const; + ModelType model_type() const; + ErrorType error_type() const; // Returns empty string is IsSet() is false. std::string ToString() const; @@ -70,7 +86,8 @@ class SYNC_EXPORT SyncError { // is called, IsSet() will return true. void Init(const tracked_objects::Location& location, const std::string& message, - ModelType type); + ModelType model_type, + ErrorType error_type); // Reset the error to it's default (unset) values. void Clear(); @@ -78,7 +95,8 @@ class SYNC_EXPORT SyncError { // scoped_ptr is necessary because Location objects aren't assignable. scoped_ptr<tracked_objects::Location> location_; std::string message_; - ModelType type_; + ModelType model_type_; + ErrorType error_type_; }; // gmock printer helper. diff --git a/sync/api/sync_error_unittest.cc b/sync/api/sync_error_unittest.cc index 71a24f1..4505ac7 100644 --- a/sync/api/sync_error_unittest.cc +++ b/sync/api/sync_error_unittest.cc @@ -26,11 +26,11 @@ TEST_F(SyncErrorTest, Default) { tracked_objects::Location location = FROM_HERE; std::string msg = "test"; ModelType type = PREFERENCES; - SyncError error(location, msg, type); + SyncError error(location, SyncError::DATATYPE_ERROR, msg, type); ASSERT_TRUE(error.IsSet()); EXPECT_EQ(location.line_number(), error.location().line_number()); - EXPECT_EQ(msg, error.message()); - EXPECT_EQ(type, error.type()); + EXPECT_EQ("datatype error was encountered: " + msg, error.message()); + EXPECT_EQ(type, error.model_type()); } TEST_F(SyncErrorTest, Reset) { @@ -45,7 +45,7 @@ TEST_F(SyncErrorTest, Reset) { ASSERT_TRUE(error.IsSet()); EXPECT_EQ(location.line_number(), error.location().line_number()); EXPECT_EQ(msg, error.message()); - EXPECT_EQ(type, error.type()); + EXPECT_EQ(type, error.model_type()); tracked_objects::Location location2 = FROM_HERE; std::string msg2 = "test"; @@ -54,7 +54,7 @@ TEST_F(SyncErrorTest, Reset) { ASSERT_TRUE(error.IsSet()); EXPECT_EQ(location2.line_number(), error.location().line_number()); EXPECT_EQ(msg2, error.message()); - EXPECT_EQ(type2, error.type()); + EXPECT_EQ(type2, error.model_type()); } TEST_F(SyncErrorTest, Copy) { @@ -71,13 +71,13 @@ TEST_F(SyncErrorTest, Copy) { ASSERT_TRUE(error1.IsSet()); EXPECT_EQ(location.line_number(), error1.location().line_number()); EXPECT_EQ(msg, error1.message()); - EXPECT_EQ(type, error1.type()); + EXPECT_EQ(type, error1.model_type()); SyncError error3(error1); ASSERT_TRUE(error3.IsSet()); EXPECT_EQ(error1.location().line_number(), error3.location().line_number()); EXPECT_EQ(error1.message(), error3.message()); - EXPECT_EQ(error1.type(), error3.type()); + EXPECT_EQ(error1.model_type(), error3.model_type()); SyncError error4; EXPECT_FALSE(error4.IsSet()); @@ -100,13 +100,13 @@ TEST_F(SyncErrorTest, Assign) { ASSERT_TRUE(error1.IsSet()); EXPECT_EQ(location.line_number(), error1.location().line_number()); EXPECT_EQ(msg, error1.message()); - EXPECT_EQ(type, error1.type()); + EXPECT_EQ(type, error1.model_type()); error2 = error1; ASSERT_TRUE(error2.IsSet()); EXPECT_EQ(error1.location().line_number(), error2.location().line_number()); EXPECT_EQ(error1.message(), error2.message()); - EXPECT_EQ(error1.type(), error2.type()); + EXPECT_EQ(error1.model_type(), error2.model_type()); error2 = SyncError(); EXPECT_FALSE(error2.IsSet()); @@ -116,8 +116,10 @@ TEST_F(SyncErrorTest, ToString) { tracked_objects::Location location = FROM_HERE; std::string msg = "test"; ModelType type = PREFERENCES; - std::string expected = "Preferences, Sync Error: test"; - SyncError error(location, msg, type); + std::string expected = std::string(ModelTypeToString(type)) + + " datatype error was encountered: " + msg; + LOG(INFO) << "Expect " << expected; + SyncError error(location, SyncError::DATATYPE_ERROR, msg, type); EXPECT_TRUE(error.IsSet()); EXPECT_NE(string::npos, error.ToString().find(expected)); diff --git a/sync/api/sync_merge_result.cc b/sync/api/sync_merge_result.cc index 0c2fb83..601c577 100644 --- a/sync/api/sync_merge_result.cc +++ b/sync/api/sync_merge_result.cc @@ -21,7 +21,7 @@ SyncMergeResult::~SyncMergeResult() { // Setters. void SyncMergeResult::set_error(SyncError error) { - DCHECK(!error.IsSet() || model_type_ == error.type()); + DCHECK(!error.IsSet() || model_type_ == error.model_type()); error_ = error; } diff --git a/sync/api/sync_merge_result_unittest.cc b/sync/api/sync_merge_result_unittest.cc index dddfa4c..b3f6927 100644 --- a/sync/api/sync_merge_result_unittest.cc +++ b/sync/api/sync_merge_result_unittest.cc @@ -24,7 +24,7 @@ TEST_F(SyncMergeResultTest, Unset) { } TEST_F(SyncMergeResultTest, SetError) { - SyncError error(FROM_HERE, "message", BOOKMARKS); + SyncError error(FROM_HERE, SyncError::DATATYPE_ERROR, "message", BOOKMARKS); SyncMergeResult merge_result(BOOKMARKS); merge_result.set_error(error); |