- Add preferences to connector. Debug logging does not yet work

- Add rudimentary connector API version checks, although I still need a good way of showing that the connector/server is out of date
- Throw new Error() in translate (so that we get a stack trace)
- Log errors in connector
This commit is contained in:
Simon Kornblith 2011-06-28 18:24:24 +00:00
parent dda8551a22
commit 0d7ffcc1c1
5 changed files with 135 additions and 25 deletions

View File

@ -22,8 +22,10 @@
***** END LICENSE BLOCK *****
*/
Zotero.Connector = new function() {
const CONNECTOR_URI = "http://127.0.0.1:23119/";
const CONNECTOR_SERVER_API_VERSION = 1;
this.isOnline = true;
this.haveRefreshedData = false;
@ -36,6 +38,18 @@ Zotero.Connector = new function() {
Zotero.Connector.getData();
}
/**
* Checks if Zotero is online and passes current status to callback
* @param {Function} callback
*/
this.checkIsOnline = function(callback) {
if(Zotero.Connector.isOnline) {
callback(true);
} else {
Zotero.Connector.getData(callback);
}
}
function _getDataFile() {
var dataFile = Zotero.getZoteroDirectory();
dataFile.append("connector.json");
@ -76,9 +90,10 @@ Zotero.Connector = new function() {
this.EXCEPTION_NOT_AVAILABLE = 0;
this.EXCEPTION_BAD_REQUEST = 400;
this.EXCEPTION_NO_ENDPOINT = 404;
this.EXCEPTION_INCOMPATIBLE_VERSION = 412;
this.EXCEPTION_CONNECTOR_INTERNAL = 500;
this.EXCEPTION_METHOD_NOT_IMPLEMENTED = 501;
this.EXCEPTION_CODES = [0, 400, 404, 500, 501];
this.EXCEPTION_CODES = [0, 400, 404, 412, 500, 501];
/**
* Updates Zotero's status depending on the success or failure of a request
@ -120,9 +135,9 @@ Zotero.Connector = new function() {
*/
this.getData = function(callback) {
Zotero.HTTP.doPost(CONNECTOR_URI+"connector/getData",
JSON.stringify({"browser":Zotero.browser}),
JSON.stringify({"browser":Zotero.browser, "apiVersion":CONNECTOR_SERVER_API_VERSION}),
function(req) {
var isOnline = req.status !== 0;
var isOnline = req.status !== 0 && req.status !== 412;
if(isOnline) {
// if request succeded, update data
@ -172,7 +187,8 @@ Zotero.Connector = new function() {
this.callMethod = function(method, data, callback) {
Zotero.HTTP.doPost(CONNECTOR_URI+"connector/"+method, JSON.stringify(data),
function(req) {
_checkState(req.status != 0, function() {
_checkState(req.status !== this.EXCEPTION_NOT_AVAILABLE
&& req.status !== this.EXCEPTION_INCOMPATIBLE_VERSION, function() {
if(!callback) return;
if(Zotero.Connector.EXCEPTION_CODES.indexOf(req.status) !== -1) {

View File

@ -0,0 +1,86 @@
/*
***** BEGIN LICENSE BLOCK *****
Copyright © 2009 Center for History and New Media
George Mason University, Fairfax, Virginia, USA
http://zotero.org
This file is part of Zotero.
Zotero is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Zotero is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with Zotero. If not, see <http://www.gnu.org/licenses/>.
***** END LICENSE BLOCK *****
*/
Zotero.Connector_Debug = new function() {
/**
* Call a callback depending upon whether debug output is being stored
*/
this.storing = function(callback) {
callback(Zotero.Debug.storing);
}
/**
* Call a callback with the lines themselves
*/
this.get = function(callback) {
callback(Zotero.Debug.get());
}
/**
* Call a callback with the number of lines of output
*/
this.count = function(callback) {
callback(Zotero.Debug.count());
}
/**
* Submit data to the sserver
*/
this.submitReport = function(callback) {
var uploadCallback = function (xmlhttp) {
var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]
.getService(Components.interfaces.nsIPromptService);
if (!xmlhttp.responseXML) {
callback(false, 'Invalid response from server');
return;
}
var reported = xmlhttp.responseXML.getElementsByTagName('reported');
if (reported.length != 1) {
callback(false, 'The server returned an error. Please try again.');
return;
}
var reportID = reported[0].getAttribute('reportID');
callback(true, reportID);
}
Zotero.HTTP.doPost("http://www.zotero.org/repo/report?debug=1", output,
function(xmlhttp) {
if (!xmlhttp.responseXML) {
callback(false, 'Invalid response from server');
return;
}
var reported = xmlhttp.responseXML.getElementsByTagName('reported');
if (reported.length != 1) {
callback(false, 'The server returned an error. Please try again.');
return;
}
var reportID = reported[0].getAttribute('reportID');
callback(true, reportID);
}, {"Content-Type":"application/octet-stream"});
}
}

View File

@ -31,6 +31,7 @@ Zotero.Server = new function() {
300:"Multiple Choices",
400:"Bad Request",
404:"Not Found",
412:"Precondition Failed",
500:"Internal Server Error",
501:"Method Not Implemented"
};

View File

@ -23,6 +23,8 @@
***** END LICENSE BLOCK *****
*/
const CONNECTOR_SERVER_API_VERSION = 1;
Zotero.Server.Connector = function() {};
Zotero.Server.Connector._waitingForSelection = {};
Zotero.Server.Connector.Data = {};
@ -227,6 +229,10 @@ Zotero.Server.Connector.GetData.prototype = {
* @param {Function} sendResponseCallback function to send HTTP response
*/
"init":function(data, sendResponseCallback) {
if(data.apiVersion !== CONNECTOR_SERVER_API_VERSION) {
sendResponseCallback(412);
}
// Translator data
var responseData = {"preferences":{}, "translators":[]};

View File

@ -122,7 +122,7 @@ Zotero.Translate.Sandbox = {
*/
"getOption":function(translate, option) {
if(typeof option !== "string") {
throw("Translate: getOption: option must be a string");
throw(new Error("getOption: option must be a string"));
return;
}
@ -149,7 +149,7 @@ Zotero.Translate.Sandbox = {
}
if(typeof type !== "string") {
throw("Translate: loadTranslator: type must be a string");
throw(new Error("loadTranslator: type must be a string"));
return;
}
@ -158,7 +158,7 @@ Zotero.Translate.Sandbox = {
translation._parentTranslator = translate;
if(translation instanceof Zotero.Translate.Export && !(translation instanceof Zotero.Translate.Export)) {
throw("Translate: only export translators may call other export translators");
throw(new Error("Only export translators may call other export translators"));
}
/**
@ -207,7 +207,7 @@ Zotero.Translate.Sandbox = {
safeTranslator.setTranslator = function(arg) {
var success = translation.setTranslator(arg);
if(!success) {
throw "Translator "+translate.translator[0].translatorID+" attempted to call invalid translatorID "+arg;
throw new Error("Translator "+translate.translator[0].translatorID+" attempted to call invalid translatorID "+arg);
}
};
safeTranslator.getTranslators = function() { return translation.getTranslators() };
@ -226,7 +226,7 @@ Zotero.Translate.Sandbox = {
if(callback) translate.incrementAsyncProcesses();
var haveTranslatorFunction = function(translator) {
translation.translator[0] = translator;
if(!Zotero._loadTranslator(translator)) throw "Translator could not be loaded";
if(!Zotero._loadTranslator(translator)) throw new Error("Translator could not be loaded");
if(Zotero.isFx) {
// do same origin check
@ -243,8 +243,8 @@ Zotero.Translate.Sandbox = {
try {
secMan.checkSameOriginURI(outerSandboxURI, innerSandboxURI, false);
} catch(e) {
throw "Translate: getTranslatorObject() may not be called from web or search "+
"translators to web or search translators from different origins.";
throw new Error("getTranslatorObject() may not be called from web or search "+
"translators to web or search translators from different origins.");
}
}
@ -262,8 +262,8 @@ Zotero.Translate.Sandbox = {
return translation._sandboxManager.sandbox;
} else {
if(Zotero.isConnector && !callback) {
throw "Translate: Translator must accept a callback to getTranslatorObject() to "+
"operate in this translation environment.";
throw new Error("Translator must accept a callback to getTranslatorObject() to "+
"operate in this translation environment.");
}
Zotero.Translators.get(translation.translator[0], haveTranslatorFunction);
@ -319,7 +319,7 @@ Zotero.Translate.Sandbox = {
*/
"selectItems":function(translate, items, callback) {
if(Zotero.Utilities.isEmpty(items)) {
throw "Translate: translator called select items with no items";
throw new Error("Translator called select items with no items");
}
if(translate._selectedItems) {
@ -423,7 +423,7 @@ Zotero.Translate.Sandbox = {
}
if(!item.title) {
throw "No title specified for item";
throw new Error("No title specified for item");
}
// create short title
@ -520,7 +520,7 @@ Zotero.Translate.Sandbox = {
*/
"nextCollection":function(translate) {
if(!translate.translator[0].configOptions.getCollections) {
throw("Translate: getCollections configure option not set; cannot retrieve collection");
throw(new Error("getCollections configure option not set; cannot retrieve collection"));
}
return translate._itemGetter.nextCollection();
@ -594,7 +594,7 @@ Zotero.Translate.Base.prototype = {
*/
"setTranslator":function(translator) {
if(!translator) {
throw new Error("Zotero.Translate: no translator specified");
throw new Error("No translator specified");
}
this.translator = null;
@ -604,7 +604,7 @@ Zotero.Translate.Base.prototype = {
if(translator.translatorID) {
this.translator = [translator];
} else {
throw("No translatorID specified");
throw(new Error("No translatorID specified"));
}
} else {
this.translator = [translator];
@ -748,7 +748,7 @@ Zotero.Translate.Base.prototype = {
*/
"getTranslators":function(getAllTranslators) {
// do not allow simultaneous instances of getTranslators
if(this._currentState == "detect") throw "Translate: getTranslators: detection is already running";
if(this._currentState == "detect") throw new Error("getTranslators: detection is already running");
this._currentState = "detect";
this._getAllTranslators = getAllTranslators;
this._getTranslatorsGetPotentialTranslators();
@ -832,7 +832,7 @@ Zotero.Translate.Base.prototype = {
this._currentState = "translate";
if(!this.translator || !this.translator.length) {
throw("Translate: Failed: no translator specified");
throw new Error("Failed: no translator specified");
}
this._libraryID = libraryID;
@ -1300,6 +1300,7 @@ Zotero.Translate.Web.prototype._translateRPCComplete = function(obj, failureCode
for(var i in obj.items) {
this._runHandler("itemDone", null, obj.items[i]);
}
this.newItems = obj.items;
this.complete(true);
}
}
@ -1551,7 +1552,7 @@ Zotero.Translate.Export.prototype._prepareTranslation = function() {
var io = this._io = new Zotero.Translate.IO.String(null, this.path ? this.path : "", this.translator[0].configOptions["dataMode"]);
this.__defineGetter__("string", function() { return io.string; });
} else if(!Zotero.Translate.IO.Write) {
throw "Translate: Writing to files is not supported in this build of Zotero.";
throw new Error("Writing to files is not supported in this build of Zotero.");
} else {
this._io = new Zotero.Translate.IO.Write(this.location,
this.translator[0].configOptions["dataMode"],
@ -1687,7 +1688,7 @@ Zotero.Translate.IO = {
var dp = Components.classes["@mozilla.org/xmlextras/domparser;1"]
.createInstance(Components.interfaces.nsIDOMParser);
} catch(e) {
throw "DOMParser not supported";
throw new Error("DOMParser not supported");
}
}
@ -1698,7 +1699,7 @@ Zotero.Translate.IO = {
}
if(nodes.getElementsByTagName("parsererror").length) {
throw("DOMParser error: loading data into data store failed");
throw new Error("DOMParser error: loading data into data store failed");
}
return nodes;
@ -1945,7 +1946,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = {
type = type.toLowerCase();
if(!containerTypes[type]) {
throw "Invalid container type in Zotero.RDF.newContainer";
throw new Error("Invalid container type in Zotero.RDF.newContainer");
}
var about = this._getResource(about);
@ -2016,7 +2017,7 @@ Zotero.Translate.IO._RDFSandbox.prototype = {
"getResourceURI":function(resource) {
if(typeof(resource) == "string") return resource;
if(resource.uri) return resource.uri;
if(resource.toNT == undefined) throw "Zotero.RDF: getResourceURI called on invalid resource";
if(resource.toNT == undefined) throw new Error("Zotero.RDF: getResourceURI called on invalid resource");
return resource.toNT();
},