commit 41eb49cf7f98dfc4e37ccae5c8364c1b9835ec7e
parent daf0f8e0b0f605973f7dd89d2aa6f3c389a42418
Author: Dan Stillman <dstillman@zotero.org>
Date: Mon, 15 Aug 2016 02:26:04 -0400
Fix handling of object-level 404/412 errors
Diffstat:
2 files changed, 52 insertions(+), 6 deletions(-)
diff --git 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
@@ -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);
+ });
});