commit bdec4b119fa116bc078a207b6030cb22cbed5435
parent 8aee80106db0f29a6d9ae72155a0cc92b7d5f01f
Author: Dan Stillman <dstillman@zotero.org>
Date: Mon, 22 Aug 2016 21:28:34 -0400
Fix error handling during local file import translation
A failure during detect (which is normal during file import attempts)
would cause later translator detection to fail.
Diffstat:
5 files changed, 56 insertions(+), 63 deletions(-)
diff --git a/chrome/content/zotero/xpcom/translation/translate.js b/chrome/content/zotero/xpcom/translation/translate.js
@@ -1595,9 +1595,15 @@ Zotero.Translate.Base.prototype = {
return;
}
- var me = this;
- this._loadTranslator(this._potentialTranslators[0]).
- then(function() { me._detectTranslatorLoaded() });
+ let lab = this._potentialTranslators[0].label;
+ this._loadTranslator(this._potentialTranslators[0])
+ .bind(this)
+ .then(function() {
+ return this._detectTranslatorLoaded();
+ })
+ .catch(function (e) {
+ this.complete(false, e);
+ });
},
/**
@@ -2146,64 +2152,31 @@ Zotero.Translate.Import.prototype.getTranslators = function() {
/**
* Overload {@link Zotero.Translate.Base#_loadTranslator} to prepare translator IO
*/
-Zotero.Translate.Import.prototype._loadTranslator = function(translator, callback) {
- // call super
- var me = this;
- return Zotero.Translate.Base.prototype._loadTranslator.call(this, translator).
- then(function() {
- me._loadTranslatorPrepareIO(translator, callback);
- });
+Zotero.Translate.Import.prototype._loadTranslator = function(translator) {
+ return Zotero.Translate.Base.prototype._loadTranslator.call(this, translator)
+ .then(function() {
+ return this._loadTranslatorPrepareIO(translator);
+ }.bind(this));
}
/**
* Prepare translator IO
*/
-Zotero.Translate.Import.prototype._loadTranslatorPrepareIO = function(translator, callback) {
+Zotero.Translate.Import.prototype._loadTranslatorPrepareIO = Zotero.Promise.method(function (translator) {
var configOptions = this._translatorInfo.configOptions;
var dataMode = configOptions ? configOptions["dataMode"] : "";
- var me = this;
- var initCallback = function(status, err) {
- if(!status) {
- me.complete(false, err);
- } else {
- me._sandboxManager.importObject(me._io);
- if(callback) callback();
- }
- };
-
- var err = false;
if(!this._io) {
if(Zotero.Translate.IO.Read && this.location && this.location instanceof Components.interfaces.nsIFile) {
- try {
- this._io = new Zotero.Translate.IO.Read(this.location, this._sandboxManager);
- } catch(e) {
- err = e;
- }
+ this._io = new Zotero.Translate.IO.Read(this.location, this._sandboxManager);
} else {
- try {
- this._io = new Zotero.Translate.IO.String(this._string, this.path ? this.path : "", this._sandboxManager);
- } catch(e) {
- err = e;
- }
- }
-
- if(err) {
- this.complete(false, err);
- return;
+ this._io = new Zotero.Translate.IO.String(this._string, this.path ? this.path : "", this._sandboxManager);
}
}
- try {
- this._io.init(dataMode, initCallback);
- } catch(e) {
- err = e;
- }
- if(err) {
- this.complete(false, err);
- return;
- }
-}
+ this._io.init(dataMode);
+ this._sandboxManager.importObject(this._io);
+});
/**
* Prepare translation
@@ -2585,7 +2558,7 @@ Zotero.Translate.IO.String.prototype = {
"getXML":"r"
},
- "_initRDF":function(callback) {
+ "_initRDF": function () {
Zotero.debug("Translate: Initializing RDF data store");
this._dataStore = new Zotero.RDF.AJAW.IndexedFormula();
this.RDF = new Zotero.Translate.IO._RDFSandbox(this._dataStore);
@@ -2600,7 +2573,6 @@ Zotero.Translate.IO.String.prototype = {
var parser = new Zotero.RDF.AJAW.RDFParser(this._dataStore);
parser.parse(xml, this._uri);
}
- callback(true);
},
"setCharacterSet":function(charset) {},
@@ -2666,20 +2638,18 @@ Zotero.Translate.IO.String.prototype = {
return (Zotero.isFx && !Zotero.isBookmarklet ? this._sandboxManager.wrap(xml) : xml);
},
- "init":function(newMode, callback) {
+ init: function (newMode) {
this.bytesRead = 0;
this._noCR = undefined;
this._mode = newMode;
if(newMode === "xml/e4x") {
- throw "E4X is not supported";
+ throw new Error("E4X is not supported");
} else if(newMode && (Zotero.Translate.IO.rdfDataModes.indexOf(newMode) !== -1
|| newMode.substr(0, 3) === "xml/dom") && this._xmlInvalid) {
- throw "XML known invalid";
+ throw new Error("XML known invalid");
} else if(Zotero.Translate.IO.rdfDataModes.indexOf(this._mode) !== -1) {
- this._initRDF(callback);
- } else {
- callback(true);
+ this._initRDF();
}
},
diff --git a/chrome/content/zotero/xpcom/translation/translate_firefox.js b/chrome/content/zotero/xpcom/translation/translate_firefox.js
@@ -845,7 +845,7 @@ Zotero.Translate.IO.Read.prototype = {
this.RDF = new Zotero.Translate.IO._RDFSandbox(this._dataStore);
} catch(e) {
this.close();
- throw "Translate: No RDF found";
+ throw new Error("Translate: No RDF found");
}
},
@@ -893,7 +893,7 @@ Zotero.Translate.IO.Read.prototype = {
return (Zotero.isFx ? this._sandboxManager.wrap(xml) : xml);
},
- "init":function(newMode, callback) {
+ init: function (newMode) {
if(Zotero.Translate.IO.maintainedInstances.indexOf(this) === -1) {
Zotero.Translate.IO.maintainedInstances.push(this);
}
@@ -901,12 +901,10 @@ Zotero.Translate.IO.Read.prototype = {
this._mode = newMode;
if(newMode === "xml/e4x") {
- throw "E4X is not supported";
+ throw new Error("E4X is not supported");
} else if(Zotero.Translate.IO.rdfDataModes.indexOf(this._mode) !== -1 && !this.RDF) {
this._initRDF();
}
-
- callback(true);
},
"close":function() {
@@ -988,7 +986,7 @@ Zotero.Translate.IO.Write.prototype = {
this._writtenToStream = true;
},
- "init":function(newMode, charset, callback) {
+ init: function (newMode, charset) {
this._mode = newMode;
if(Zotero.Translate.IO.rdfDataModes.indexOf(this._mode) !== -1) {
this._initRDF();
diff --git a/chrome/content/zotero/xpcom/translation/translators.js b/chrome/content/zotero/xpcom/translation/translators.js
@@ -342,8 +342,9 @@ Zotero.Translators = new function() {
* Gets import translators for a specific location
* @param {String} location The location for which to look for translators
* @param {Function} [callback] An optional callback to be executed when translators have been
- * retrieved. If no callback is specified, translators are
- * returned.
+ * retrieved
+ * @return {Promise<Zotero.Translator[]|true>} - An array of translators if no callback is specified;
+ * otherwise true
*/
this.getImportTranslatorsForLocation = function(location, callback) {
return Zotero.Translators.getAllForType("import").then(function(allTranslators) {
diff --git a/test/tests/data/mods.xml b/test/tests/data/mods.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0"?>
+<modsCollection xmlns="http://www.loc.gov/mods/v3" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.loc.gov/mods/v3 http://www.loc.gov/standards/mods/v3/mods-3-2.xsd">
+ <mods>
+ <titleInfo>
+ <title>Test</title>
+ </titleInfo>
+ <typeOfResource>text</typeOfResource>
+ <genre authority="local">journalArticle</genre>
+ </mods>
+</modsCollection>
+\ No newline at end of file
diff --git a/test/tests/fileInterfaceTest.js b/test/tests/fileInterfaceTest.js
@@ -73,4 +73,17 @@ describe("Zotero_File_Interface", function() {
assert.lengthOf(matches, 1);
assert.propertyVal(matches[0], 'id', attachment.id);
});
+
+ it('should import a MODS file', function* () {
+ var modsFile = OS.Path.join(getTestDataDirectory().path, "mods.xml");
+
+ var promise = waitForItemEvent('add');
+ yield win.Zotero_File_Interface.importFile(Zotero.File.pathToFile(modsFile));
+ var ids = yield promise;
+ assert.lengthOf(ids, 1);
+
+ var item = Zotero.Items.get(ids[0]);
+ assert.equal(item.itemTypeID, Zotero.ItemTypes.getID('journalArticle'));
+ assert.equal(item.getField('title'), "Test");
+ });
});
\ No newline at end of file