diff --git a/chrome/content/zotero/xpcom/sync/syncEngine.js b/chrome/content/zotero/xpcom/sync/syncEngine.js index 92cd4a177..fb5e62a86 100644 --- a/chrome/content/zotero/xpcom/sync/syncEngine.js +++ b/chrome/content/zotero/xpcom/sync/syncEngine.js @@ -1011,20 +1011,20 @@ Zotero.Sync.Data.Engine.prototype._uploadObjects = Zotero.Promise.coroutine(func Zotero.logError("Error for " + objectType + " " + batch[index].key + " in " + this.library.name + ":\n\n" + e); - // This shouldn't happen, because the upload request includes a library - // version and should prevent an outdated upload before the object version is - // checked. If it does, we need to do a full sync. + // This shouldn't happen, because the upload request includes a library version and should + // prevent an outdated upload before the object version is checked. If it does, we need to + // do a full sync. This error is checked in handleUploadError(). // TEMP - Revert after 2016-08-19 //if (e.code == 412) { if (e.code == 404 || e.code == 412) { - return this.UPLOAD_RESULT_OBJECT_CONFLICT; + throw e; } if (this.onError) { this.onError(e); } if (this.stopOnError) { - throw new Error(e); + throw e; } batch[index].tries++; // Mark 400 errors as permanently failed @@ -1477,11 +1477,19 @@ Zotero.Sync.Data.Engine.prototype._handleUploadError = Zotero.Promise.coroutine( return this.UPLOAD_RESULT_CANCEL; } throw new Error(`Unexpected index value ${index}`); - + case 412: return this.UPLOAD_RESULT_LIBRARY_CONFLICT; } } + else if (e.name == "ZoteroObjectUploadError") { + switch (e.code) { + // TEMP - Revert after 2016-08-19 + case 404: + case 412: + return this.UPLOAD_RESULT_OBJECT_CONFLICT; + } + } throw e; }); diff --git a/test/tests/syncEngineTest.js b/test/tests/syncEngineTest.js index 982964196..b36730216 100644 --- a/test/tests/syncEngineTest.js +++ b/test/tests/syncEngineTest.js @@ -2136,6 +2136,44 @@ describe("Zotero.Sync.Data.Engine", function () { // Library version shouldn't have changed assert.equal(group.libraryVersion, 5); }); + + + it("should trigger full sync on object conflict", function* () { + ({ engine, client, caller } = yield setup()); + + var library = Zotero.Libraries.userLibrary; + var libraryID = library.id; + var lastLibraryVersion = 5; + library.libraryVersion = lastLibraryVersion; + yield library.saveTx(); + + var item = createUnsavedDataObject('item'); + item.version = lastLibraryVersion; + yield item.saveTx(); + + setResponse({ + method: "POST", + url: "users/1/items", + status: 200, + headers: { + "Last-Modified-Version": lastLibraryVersion + }, + json: { + successful: {}, + unchanged: {}, + failed: { + "0": { + "code": 412, + "message": `Item doesn't exist (expected version ${lastLibraryVersion}; ` + + "use 0 instead)" + } + } + } + }); + + var result = yield engine._startUpload(); + assert.equal(result, engine.UPLOAD_RESULT_OBJECT_CONFLICT); + }); });