Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(534)

Side by Side Diff: chrome/browser/sync/engine/syncer_proto_util.cc

Issue 7621085: Server directed error handling backend code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: For review. Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/sync/engine/syncer_proto_util.h" 5 #include "chrome/browser/sync/engine/syncer_proto_util.h"
6 6
7 #include "base/format_macros.h" 7 #include "base/format_macros.h"
8 #include "base/stringprintf.h" 8 #include "base/stringprintf.h"
9 #include "chrome/browser/sync/engine/net/server_connection_manager.h" 9 #include "chrome/browser/sync/engine/net/server_connection_manager.h"
10 #include "chrome/browser/sync/engine/syncer.h" 10 #include "chrome/browser/sync/engine/syncer.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 } 93 }
94 session->status_controller()->set_types_needing_local_migration(to_migrate); 94 session->status_controller()->set_types_needing_local_migration(to_migrate);
95 } 95 }
96 96
97 // static 97 // static
98 bool SyncerProtoUtil::VerifyResponseBirthday(syncable::Directory* dir, 98 bool SyncerProtoUtil::VerifyResponseBirthday(syncable::Directory* dir,
99 const ClientToServerResponse* response) { 99 const ClientToServerResponse* response) {
100 100
101 std::string local_birthday = dir->store_birthday(); 101 std::string local_birthday = dir->store_birthday();
102 102
103 // TODO(lipalani) : Remove this check here. When the new implementation
104 // becomes the default this check should go away. This is handled by the
105 // switch case in the new implementation.
103 if (response->error_code() == ClientToServerResponse::CLEAR_PENDING || 106 if (response->error_code() == ClientToServerResponse::CLEAR_PENDING ||
104 response->error_code() == ClientToServerResponse::NOT_MY_BIRTHDAY) { 107 response->error_code() == ClientToServerResponse::NOT_MY_BIRTHDAY) {
105 // Birthday verification failures result in stopping sync and deleting 108 // Birthday verification failures result in stopping sync and deleting
106 // local sync data. 109 // local sync data.
107 return false; 110 return false;
108 } 111 }
109 112
110 if (local_birthday.empty()) { 113 if (local_birthday.empty()) {
111 if (!response->has_store_birthday()) { 114 if (!response->has_store_birthday()) {
112 LOG(WARNING) << "Expected a birthday on first sync."; 115 LOG(WARNING) << "Expected a birthday on first sync.";
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
204 if (!message.has_get_updates()) 207 if (!message.has_get_updates())
205 return false; 208 return false;
206 DCHECK_LT(0, message.get_updates().from_progress_marker_size()); 209 DCHECK_LT(0, message.get_updates().from_progress_marker_size());
207 for (int i = 0; i < message.get_updates().from_progress_marker_size(); ++i) { 210 for (int i = 0; i < message.get_updates().from_progress_marker_size(); ++i) {
208 if (!message.get_updates().from_progress_marker(i).token().empty()) 211 if (!message.get_updates().from_progress_marker(i).token().empty())
209 return false; 212 return false;
210 } 213 }
211 return true; 214 return true;
212 } 215 }
213 216
217 sync_api::SyncErrorType ConvertSyncErrorTypePBToLocalType(
218 const sync_pb::ClientToServerResponse::ErrorType& error_type) {
219 switch (error_type) {
220 case ClientToServerResponse::SUCCESS:
221 return sync_api::SUCCESS;
222 case ClientToServerResponse::NOT_MY_BIRTHDAY:
223 return sync_api::NOT_MY_BIRTHDAY;
224 case ClientToServerResponse::THROTTLED:
225 return sync_api::THROTTLED;
226 case ClientToServerResponse::CLEAR_PENDING:
227 return sync_api::CLEAR_PENDING;
228 case ClientToServerResponse::TRANSIENT_ERROR:
229 return sync_api::TRANSIENT_ERROR;
230 case ClientToServerResponse::MIGRATION_DONE:
231 return sync_api::MIGRATION_DONE;
232 case ClientToServerResponse::UNKNOWN:
233 return sync_api::UNKNOWN_ERROR;
234 case ClientToServerResponse::USER_NOT_ACTIVATED:
235 case ClientToServerResponse::AUTH_INVALID:
236 case ClientToServerResponse::ACCESS_DENIED:
237 return sync_api::INVALID_CREDENTIAL;
238 default:
239 NOTREACHED();
240 return sync_api::UNKNOWN_ERROR;
241 }
242 }
243
244 sync_api::ClientAction ConvertClientActionPBToLocalClientAction(
245 const sync_pb::ClientToServerResponse::Error::Action& action) {
246 switch (action) {
247 case ClientToServerResponse::Error::UPGRADE_CLIENT:
248 return sync_api::UPGRADE_CLIENT;
249 case ClientToServerResponse::Error::CLEAR_USER_DATA_AND_RESYNC:
250 return sync_api::CLEAR_USER_DATA_AND_RESYNC;
251 case ClientToServerResponse::Error::ENABLE_SYNC_ON_ACCOUNT:
252 return sync_api::ENABLE_SYNC_ON_ACCOUNT;
253 case ClientToServerResponse::Error::STOP_AND_RESTART_SYNC:
254 return sync_api::STOP_AND_RESTART_SYNC;
255 case ClientToServerResponse::Error::DISABLE_SYNC_ON_CLIENT:
256 return sync_api::DISABLE_SYNC_ON_CLIENT;
257 case ClientToServerResponse::Error::UNKNOWN_ACTION:
258 return sync_api::UNKNOWN_ACTION;
259 default:
260 NOTREACHED();
261 return sync_api::UNKNOWN_ACTION;
262 }
263 }
264
265 sync_api::SyncError ConvertErrorPBToLocalType(
266 const sync_pb::ClientToServerResponse::Error& error) {
267 sync_api::SyncError sync_error;
268 sync_error.error_type = ConvertSyncErrorTypePBToLocalType(error.error_type());
269 sync_error.error_description = error.error_description();
270 sync_error.url = error.url();
271 sync_error.action = ConvertClientActionPBToLocalClientAction(error.action());
272
273 return sync_error;
274 }
275
214 } // namespace 276 } // namespace
215 277
278 bool ShouldRequestEarlyExit(const sync_api::SyncError& error) {
tim (not reviewing) 2011/08/22 15:14:57 Having this method here is a layering violation in
lipalani1 2011/08/22 21:43:53 hmm... This is how it is currently implemented and
tim (not reviewing) 2011/08/23 14:17:07 That's because we used an existing error ("birthda
279 switch (error.error_type) {
280 case sync_api::SUCCESS:
281 case sync_api::MIGRATION_DONE:
282 return false;
283 case sync_api::NOT_MY_BIRTHDAY:
284 case sync_api::THROTTLED:
tim (not reviewing) 2011/08/22 15:14:57 We shouldn't be requesting early exit on throttled
lipalani1 2011/08/22 21:43:53 Done.
285 case sync_api::CLEAR_PENDING:
286 case sync_api::TRANSIENT_ERROR:
tim (not reviewing) 2011/08/22 15:14:57 We definitely should not be requesting early exit
lipalani1 2011/08/22 21:43:53 Agree. it has already caused grievance for me :) W
287 case sync_api::INVALID_CREDENTIAL:
tim (not reviewing) 2011/08/22 15:14:57 I think (as we discussed in review meetings) inval
lipalani1 2011/08/22 21:43:53 It is a seperate case. The event for 401 error is
tim (not reviewing) 2011/08/23 14:17:07 I agree with what you say here, but I still don't
288 return true;
289 // Make the default a NOTREACHED. So if a new error is introduced we
290 // think about its expected functionality.
291 default:
292 NOTREACHED();
293 return false;
294 }
295 }
296
297 bool IsActionableError(const sync_api::SyncError& error) {
298 return (error.action != sync_api::UNKNOWN_ACTION);
299 }
300
216 // static 301 // static
217 bool SyncerProtoUtil::PostClientToServerMessage( 302 bool SyncerProtoUtil::PostClientToServerMessage(
218 const ClientToServerMessage& msg, 303 const ClientToServerMessage& msg,
219 ClientToServerResponse* response, 304 ClientToServerResponse* response,
220 SyncSession* session) { 305 SyncSession* session) {
221 306
222 CHECK(response); 307 CHECK(response);
223 DCHECK(!msg.get_updates().has_from_timestamp()); // Deprecated. 308 DCHECK(!msg.get_updates().has_from_timestamp()); // Deprecated.
224 DCHECK(!msg.get_updates().has_requested_types()); // Deprecated. 309 DCHECK(!msg.get_updates().has_requested_types()); // Deprecated.
225 DCHECK(msg.has_store_birthday() || IsVeryFirstGetUpdates(msg)) 310 DCHECK(msg.has_store_birthday() || IsVeryFirstGetUpdates(msg))
226 << "Must call AddRequestBirthday to set birthday."; 311 << "Must call AddRequestBirthday to set birthday.";
227 312
228 ScopedDirLookup dir(session->context()->directory_manager(), 313 ScopedDirLookup dir(session->context()->directory_manager(),
229 session->context()->account_name()); 314 session->context()->account_name());
230 if (!dir.good()) 315 if (!dir.good())
231 return false; 316 return false;
232 317
233 if (!PostAndProcessHeaders(session->context()->connection_manager(), session, 318 if (!PostAndProcessHeaders(session->context()->connection_manager(), session,
234 msg, response)) 319 msg, response))
235 return false; 320 return false;
236 321
322 if (response->has_error()) {
323 // We are talking to a server that is capable of sending the |error| tag.
324 sync_api::SyncError sync_error = ConvertErrorPBToLocalType(
325 response->error());
326 sessions::StatusController* status = session->status_controller();
327 status->set_sync_error(sync_error);
328
329 // Birthday mismatch overrides any error that is sent by the server.
330 if (!VerifyResponseBirthday(dir, response)) {
331 sync_error.error_type = sync_api::NOT_MY_BIRTHDAY;
332 sync_error.action = sync_api::DISABLE_SYNC_ON_CLIENT;
333 }
334
335 // Inform the syncer if we need to exit early.
336 if (ShouldRequestEarlyExit(sync_error)) {
337 session->status_controller()->set_syncer_stuck(true);
338 session->delegate()->OnRequestEarlyExit();
339 }
340
341 // Inform the syncer if there is an actionable error.
342 if (IsActionableError(sync_error)) {
343 session->delegate()->OnActionableError(session);
344 }
345
346 // Now do any special handling for the error type and decide on the return
347 // value.
348 switch (sync_error.error_type) {
349 case sync_api::UNKNOWN_ERROR:
350 LOG(WARNING) << "Sync protocol out-of-date. The server is using a more "
351 << "recent version.";
352 return false;
353 case sync_api::SUCCESS:
354 LogResponseProfilingData(*response);
355 return true;
356 case sync_api::THROTTLED:
357 LOG(WARNING) << "Client silenced by server.";
358 session->delegate()->OnSilencedUntil(base::TimeTicks::Now() +
359 GetThrottleDelay(*response));
360 return false;
361 case sync_api::TRANSIENT_ERROR:
362 return false;
363 case sync_api::MIGRATION_DONE:
364 HandleMigrationDoneResponse(response, session);
365 return false;
366 default:
367 NOTREACHED();
368 return false;
369 }
370 }
371
372 // TODO(lipalani): Plug this legacy implementation to the new error framework.
373 // New implementation code would have returned before by now. This is waiting
374 // on the frontend code being implemented. Otherwise ripping this would break
375 // sync.
237 if (!VerifyResponseBirthday(dir, response)) { 376 if (!VerifyResponseBirthday(dir, response)) {
238 session->status_controller()->set_syncer_stuck(true); 377 session->status_controller()->set_syncer_stuck(true);
239 session->delegate()->OnShouldStopSyncingPermanently(); 378 session->delegate()->OnShouldStopSyncingPermanently();
240 return false; 379 return false;
241 } 380 }
242 381
243 switch (response->error_code()) { 382 switch (response->error_code()) {
244 case ClientToServerResponse::UNKNOWN: 383 case ClientToServerResponse::UNKNOWN:
245 LOG(WARNING) << "Sync protocol out-of-date. The server is using a more " 384 LOG(WARNING) << "Sync protocol out-of-date. The server is using a more "
246 << "recent version."; 385 << "recent version.";
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 std::string SyncerProtoUtil::ClientToServerResponseDebugString( 529 std::string SyncerProtoUtil::ClientToServerResponseDebugString(
391 const sync_pb::ClientToServerResponse& response) { 530 const sync_pb::ClientToServerResponse& response) {
392 // Add more handlers as needed. 531 // Add more handlers as needed.
393 std::string output; 532 std::string output;
394 if (response.has_get_updates()) 533 if (response.has_get_updates())
395 output.append(GetUpdatesResponseString(response.get_updates())); 534 output.append(GetUpdatesResponseString(response.get_updates()));
396 return output; 535 return output;
397 } 536 }
398 537
399 } // namespace browser_sync 538 } // namespace browser_sync
OLDNEW
« no previous file with comments | « chrome/browser/sync/engine/syncer_proto_util.h ('k') | chrome/browser/sync/engine/syncer_proto_util_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698