improved error handling

This commit is contained in:
CodePoet80 committed 2021-05-27 17:10:49 -04:00
1 parent 1f99489737
commit 946d21b431
5 files changed
+130 -172

No files matched your search

+38 -47
View File
@@ -75,16 +75,7 @@ LoginAssistant.prototype.activate = function(event) {
};
LoginAssistant.prototype.handleValueChange = function(event) {
//Mojo.Log.info(event.srcElement.title + " now: " + event.value);
/*if (event.srcElement.title == "Username" && event.value.toLowerCase() == "jjj" && devModeChessMove && devModeGrandmaster) {
Mojo.Controller.getAppController().showBanner("Dev mode enabled!", { source: 'notification' });
Mojo.Log.warn("Switching to Developer Mode! " + devModeChessMove);
appModel.AppSettingsCurrent["Username"] = devModeChessMove;
appModel.AppSettingsCurrent["Credential"] = devModeGrandmaster;
} else {*/
//We stashed the preference name in the title of the HTML element, so we don't have to use a case statement
appModel.AppSettingsCurrent[event.srcElement.title] = event.value;
//}
appModel.AppSettingsCurrent[event.srcElement.title] = event.value;
}
LoginAssistant.prototype.handleCancelPress = function(event) {
@@ -94,45 +85,35 @@ LoginAssistant.prototype.handleCancelPress = function(event) {
LoginAssistant.prototype.handleGoPress = function(event) {
if (this.sceneAssistant.controller.get("txtUsername").mojo.getValue() == "") {
this.sceneAssistant.controller.get("txtUsername").mojo.focus();
this.sceneAssistant.controller.get("goButton").mojo.deactivate();
return;
}
if (this.sceneAssistant.controller.get("txtCredential").mojo.getValue() == "") {
this.sceneAssistant.controller.get("txtCredential").mojo.focus();
this.sceneAssistant.controller.get("goButton").mojo.deactivate();
return;
}
//Update UI for this state
this.sceneAssistant.controller.get("addressError").style.display = "none";
this.sceneAssistant.controller.get("linkError").style.display = "none";
this.tryServiceLogin(this.handleLoginResponse.bind(this));
this.tryServiceLogin();
}
LoginAssistant.prototype.tryServiceLogin = function(callback) {
serviceModel.DoShareListRequest(appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], callback);
}
LoginAssistant.prototype.handleLoginResponse = function(response) {
Mojo.Log.info("login response was: " + response);
try {
var responseObj = JSON.parse(response);
} catch (ex) {
Mojo.Log.error("Could not parse login response: " + response);
//Show error message
Mojo.Controller.errorDialog("The server response to the log in request was malformed. Login failed.");
//Dismiss this dialog
this.doneCallBack(false);
this.widget.mojo.close();
}
if (responseObj && responseObj.shares && responseObj.shares != "") {
Mojo.Log.info("Login success!");
//appModel.AppSettingsCurrent["Username"] = responseObj.notation;
appModel.SaveSettings();
//Dismiss this dialog
this.doneCallBack(true);
this.widget.mojo.close();
} else {
Mojo.Log.warn("Login failure: " + response);
//Show error message
Mojo.Controller.errorDialog("Login failure. Check connectivity and your credentials. If you haven't logged in for a long time, create a new account.");
//Dismiss this dialog
this.doneCallBack(false);
this.widget.mojo.close();
}
LoginAssistant.prototype.tryServiceLogin = function() {
serviceModel.DoShareListRequest(appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], function(response) {
if (response.error) {
this.doneCallBack(response);
} else {
if (response && response.shares && response.shares != "") {
Mojo.Log.info("Login success!");
appModel.SaveSettings();
this.doneCallBack(true);
} else {
this.doneCallBack({"error": "Login failure. Check connectivity and your credentials. If you haven't logged in for a long time, create a new account."});
}
}
this.widget.mojo.close(); //Dismiss this dialog
}.bind(this), this.errorHandler.bind(this));
}
LoginAssistant.prototype.deactivate = function(event) {
@@ -149,4 +130,14 @@ LoginAssistant.prototype.cleanup = function(event) {
Mojo.Log.info("Login assistant cleaned up");
/* this function should do any cleanup needed before the scene is destroyed as
a result of being popped off the scene stack */
};
};
LoginAssistant.prototype.errorHandler = function (errorText, callback) {
Mojo.Log.error(errorText);
if (callback) {
callback.bind(this);
callback({"error": errorText});
} else {
Mojo.Controller.getAppController().showBanner({ messageText: errorText, icon: "images/notify.png" }, "", "");
}
}
+47 -35
View File
@@ -16,6 +16,7 @@ MainAssistant.prototype.setup = function() {
//Load preferences
appModel.LoadSettings();
Mojo.Log.info("settings now: " + JSON.stringify(appModel.AppSettingsCurrent));
this.errorCount = 0;
//Loading spinner - with global members for easy toggling later
this.spinnerAttrs = {
@@ -167,6 +168,7 @@ MainAssistant.prototype.activate = function(event) {
this.showWelcomePrompt();
}
}
//Check if we're registered to handle URLs
useShortLink = Mojo.Controller.appInfo.shortURL;
if (appModel.AppSettingsCurrent["UseCustomEndpoint"] && appModel.AppSettingsCurrent["ShortURL"] && appModel.AppSettingsCurrent["ShortURL"] != "")
@@ -282,17 +284,30 @@ MainAssistant.prototype.handlePopupChoose = function(share, command) {
/* Get Share Stuff */
MainAssistant.prototype.fetchShares = function() {
serviceModel.DoShareListRequest(appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], this.handleServerResponse.bind(this));
serviceModel.DoShareListRequest(appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], this.handleServerResponse.bind(this), this.errorHandler.bind(this));
}
MainAssistant.prototype.handleServerResponse = function(response) {
Mojo.Log.info("ready to process share list: " + response);
MainAssistant.prototype.errorHandler = function (errorText, callback) {
this.errorCount++;
Mojo.Log.error("error count: " + this.errorCount + ", " + errorText);
if (this.errorCount > 5) {
Mojo.Additions.ShowDialogBox("Sync Error", errorText);
clearInterval(this.refreshInt);
Mojo.Controller.getAppController().showBanner({ messageText: "Sync offline", icon: "images/notify.png" }, "", "");
}
if (callback) {
callback.bind(this);
callback({"error": errorText});
}
}
MainAssistant.prototype.handleServerResponse = function(responseObj) {
Mojo.Log.info("ready to process share list: " + JSON.stringify(responseObj));
if (response != null && response != "") {
var responseObj = JSON.parse(response);
if (responseObj != null) {
if (responseObj.status == "error") {
Mojo.Log.error("Error message from server while loading shares: " + responseObj.msg);
Mojo.Controller.errorDialog("The server responded to the share list request with: " + responseObj.msg.replace("ERROR: ", ""));
this.errorHandler("The server responded to the share list request with: " + responseObj.msg.replace("ERROR: ", ""));
} else {
if (responseObj.shares) {
//If we got a good looking response update the UI
@@ -303,12 +318,11 @@ MainAssistant.prototype.handleServerResponse = function(response) {
}
} else {
Mojo.Log.warn("Share list was empty. Either there was no matching result, or there were server or connectivity problems.");
Mojo.Additions.ShowDialogBox("No shares", "The server did not report any shares for the specified username.");
}
}
} else {
Mojo.Log.error("No usable response from server while loading shares: " + response);
Mojo.Controller.errorDialog("The server did not answer with a usable response to the share list request. Check network connectivity, SSL and/or self-host settings.");
this.errorHandler("The server did not answer with a usable response to the share list request. Check network connectivity, SSL and/or self-host settings.");
}
}
@@ -331,6 +345,7 @@ MainAssistant.prototype.updateShareListWidget = function(username, results, acce
Mojo.Log.info("Updating share list widget with " + results.length + " results!");
this.controller.get("showShareList").style.display = "block";
this.controller.modelChanged(thisShareList.model);
this.errorCount = 0;
}
/* New Share Stuff */
@@ -364,19 +379,19 @@ MainAssistant.prototype.invokeFilePicker = function() {
var self = this; //Retain the reference for the callback
var params = { kind: 'image', actionName: 'Share Photo',
onSelect: function(file){
Mojo.Log.info("selected file was: " + JSON.stringify(file));
Mojo.Controller.getAppController().showBanner({ messageText: 'Sharing image...', icon: 'images/notify.png' }, { source: 'notification' });
Mojo.Log.info("selected file was: " + JSON.stringify(file));
Mojo.Controller.getAppController().showBanner({ messageText: 'Sharing image...', icon: 'images/notify.png' }, { source: 'notification' });
//Figure out what mimetype to use
var ext = file.fullPath.split(".");
ext = ext[ext.length - 1].toLowerCase();
if (ext == "jpg")
mimetype = "image/jpeg";
else
mimetype = "image/" + ext;
serviceModel.DoShareAddRequestImage(file.fullPath, appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], mimetype);
}
//Figure out what mimetype to use
var ext = file.fullPath.split(".");
ext = ext[ext.length - 1].toLowerCase();
if (ext == "jpg")
mimetype = "image/jpeg";
else
mimetype = "image/" + ext;
serviceModel.DoShareAddRequestImage(file.fullPath, appModel.AppSettingsCurrent["Username"], appModel.AppSettingsCurrent["Credential"], mimetype);
}
}
Mojo.FilePicker.pickFile(params, this.controller.stageController);
}
@@ -431,25 +446,22 @@ MainAssistant.prototype.showLogin = function() {
this.controller = stageController.activeScene();
this.controller.showDialog({
template: 'login/login-scene',
assistant: new LoginAssistant(this, function(val) {
Mojo.Log.info("got value from login dialog: " + val);
this.handleLoginDialogDone(val);
}.bind(this)) //since this will be a dialog, not a scene, it must be defined in sources.json without a 'scenes' member
assistant: new LoginAssistant(this, function(dialogResponse) {
if (dialogResponse == true) {
Mojo.Log.info("Re-painting scene after successful login!");
//Re-paint scene
var stageController = Mojo.Controller.getAppController().getActiveStageController();
stageController.swapScene({ transition: Mojo.Transition.crossFade, name: "main", disableSceneScroller: false });
} else {
var readableError = dialogResponse.error.replace("Share service error: ", "");
readableError = readableError.charAt(0).toUpperCase() + readableError.slice(1);
Mojo.Additions.ShowDialogBox("Share Service Error", readableError);
}
}.bind(this))
});
}
}
MainAssistant.prototype.handleLoginDialogDone = function(val) {
if (val) {
Mojo.Log.info("Re-painting scene after successful login!");
//Re-paint scene
var stageController = Mojo.Controller.getAppController().getActiveStageController();
stageController.swapScene({ transition: Mojo.Transition.crossFade, name: "main", disableSceneScroller: false });
} else {
//multiple reasons we could have got a false
}
}
/* End of Life Stuff */
MainAssistant.prototype.deactivate = function(event) {
+1 -1
View File
@@ -91,7 +91,7 @@ NewshareAssistant.prototype.handleOKPress = function(event) {
} catch (ex) {
Mojo.Controller.getAppController().showBanner({ messageText: 'JSON content not be parsed', icon: 'images/notify.png' }, { source: 'notification' });
this.controller.get('goButton').mojo.deactivate();
setTimeout(this.controller.get('txtShareContent').mojo.focus(), 500);
this.controller.window.setTimeout(this.controller.get('txtShareContent').mojo.focus(), 500);
return false;
}
}
+44 -82
View File
@@ -41,7 +41,7 @@ ShareServiceModel.prototype.buildURL = function(username, actionType) {
}
//HTTP request for list files
ShareServiceModel.prototype.DoShareListRequest = function(username, credential, callback) {
ShareServiceModel.prototype.DoShareListRequest = function(username, credential, callback, errorhandler) {
this.retVal = "";
if (callback)
callback = callback.bind(this);
@@ -55,48 +55,40 @@ ShareServiceModel.prototype.DoShareListRequest = function(username, credential,
xmlhttp.send();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 404) {
Mojo.Log.error("Share service returned 404 sharing content. If the service is online, there's probably a version mismatch between service and client.");
Mojo.Controller.getAppController().showBanner({ messageText: "Error sharing: 404 at endpoint" }, "", "");
if (callback) callback(false);
if (xmlhttp.status >= 400) {
errorhandler(xmlhttp.status + " Error getting share list: " + responseObj.error, callback);
return false;
} else {
if (xmlhttp.responseText && xmlhttp.responseText != "") {
try {
var responseObj = JSON.parse(xmlhttp.responseText);
if (responseObj.error) {
Mojo.Log.error("Share service returned error: " + responseObj.error);
Mojo.Controller.getAppController().showBanner({ messageText: "Error getting shares: " + responseObj.error }, "", "");
if (callback) {
callback(xmlhttp.responseText);
return false;
}
errorhandler("Share service error: " + responseObj.error, callback);
return false;
} else {
//Mojo.Log.info("Share List success! " + xmlhttp.responseText);
if (callback) {
callback(xmlhttp.responseText);
callback(responseObj);
} else {
Mojo.Controller.getAppController().showBanner({ messageText: "Content shared!" }, "", "");
Mojo.Controller.getAppController().showBanner({ messageText: "Shares retreived!" }, "", "");
}
return true;
}
} catch (ex) {
Mojo.Controller.getAppController().showBanner({ messageText: "Error getting shares: server response malformed" }, "", "");
Mojo.Log.error("Share service response could not be parsed, error was: " + ex + ", response: " + xmlhttp.responseText);
errorhandler("Error parsing Share list response: " + ex + ", response: " + xmlhttp.responseText, callback);
return false;
}
} else {
Mojo.Controller.getAppController().showBanner({ messageText: "Error getting shares: server response empty" }, "", "");
Mojo.Log.error("Share service response was empty: " + xmlhttp.responseText);
errorhandler("Share list response was empty", callback);
return false;
}
if (callback) callback(false);
return false;
}
}
}.bind(this);
}
//HTTP request for add file
ShareServiceModel.prototype.DoShareAddRequestText = function(content, username, credential, contenttype, callback) {
ShareServiceModel.prototype.DoShareAddRequestText = function(content, username, credential, contenttype, callback, errorhandler) {
var useURL = this.buildURL(username, "share-text");
Mojo.Log.info("Adding text share: " + content + " of type " + contenttype + " from URL " + useURL);
@@ -112,10 +104,8 @@ ShareServiceModel.prototype.DoShareAddRequestText = function(content, username,
xmlhttp.send(content);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 404) {
Mojo.Log.error("Share service returned 404 sharing content. If the service is online, there's probably a version mismatch between service and client.");
Mojo.Controller.getAppController().showBanner({ messageText: "Error sharing: 404 at endpoint" }, "", "");
if (callback) callback(false);
if (xmlhttp.status >= 400) {
errorhandler(xmlhttp.status + " Error adding share text: " + responseObj.error);
return false;
} else {
Mojo.Log.info("Share service sent response while sharing text: " + xmlhttp.responseText);
@@ -124,8 +114,8 @@ ShareServiceModel.prototype.DoShareAddRequestText = function(content, username,
try {
var responseObj = JSON.parse(xmlhttp.responseText);
if (responseObj.error) {
Mojo.Log.error("Share service returned error: " + responseObj.error);
Mojo.Controller.getAppController().showBanner({ messageText: "Error sharing: " + responseObj.error }, "", "");
errorhandler("Error sharing text: " + responseObj.error);
return false;
} else {
Mojo.Log.info("Share success! " + xmlhttp.responseText);
if (callback) {
@@ -136,22 +126,20 @@ ShareServiceModel.prototype.DoShareAddRequestText = function(content, username,
return true;
}
} catch (ex) {
Mojo.Controller.getAppController().showBanner({ messageText: "Error sharing: server response malformed" }, "", "");
Mojo.Log.error("Share service response could not be parsed, error was: " + ex + ", response: " + xmlhttp.responseText);
errorhandler("Error parsing add Share response: " + ex);
return false;
}
} else {
Mojo.Controller.getAppController().showBanner({ messageText: "Error sharing: server response empty" }, "", "");
Mojo.Log.error("Share service response was empty: " + xmlhttp.responseText);
errorhandler("Add Share response was empty");
return false;
}
if (callback) callback(false);
return false;
}
}
}.bind(this);
}
//Upload a file
ShareServiceModel.prototype.DoShareAddRequestImage = function (fullFilePath, username, credential, contenttype, callback) {
ShareServiceModel.prototype.DoShareAddRequestImage = function (fullFilePath, username, credential, contenttype, callback, errorhandler) {
if (!fullFilePath){
Mojo.Log.error("Image file path not supplied");
@@ -190,12 +178,8 @@ ShareServiceModel.prototype.DoShareAddRequestImage = function (fullFilePath, use
if (response.responseString) {
var responseObj = JSON.parse(response.responseString);
if (responseObj.error) {
Mojo.Log.error("Upload Error: ", responseObj.error);
if (callback) {
callback(responseObj.error);
} else {
Mojo.Controller.getAppController().showBanner({ messageText: "Upload error: " + responseObj.error }, "", "");
}
errorhandler("Error deleting share: " + responseObj.error);
return false;
} else {
Mojo.Log.info("Upload response: " + response.responseString);
if (callback) {
@@ -209,19 +193,14 @@ ShareServiceModel.prototype.DoShareAddRequestImage = function (fullFilePath, use
}
},
onFailure: function(response) {
Mojo.Log.error("Upload Failure: ", JSON.stringify(response));
if (callback) {
callback(response.responseString);
return false;
} else {
Mojo.Controller.getAppController().showBanner({ messageText: "Upload error:" + JSON.stringify(response.responseString.error) }, "", "");
}
errorhandler("Error uploading image share: " + response);
return false;
}
});
}
//HTTP request for list files
ShareServiceModel.prototype.DoShareDeleteRequest = function(itemid, username, credential, callback) {
ShareServiceModel.prototype.DoShareDeleteRequest = function(itemid, username, credential, callback, errorhandler) {
this.retVal = "";
if (callback)
callback = callback.bind(this);
@@ -236,25 +215,18 @@ ShareServiceModel.prototype.DoShareDeleteRequest = function(itemid, username, cr
xmlhttp.send();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 404) {
Mojo.Log.error("Share service returned 404 deleting content. If the service is online, there's probably a version mismatch between service and client.");
Mojo.Controller.getAppController().showBanner({ messageText: "Error sharing: 404 at endpoint" }, "", "");
if (callback) callback(false);
if (xmlhttp.status >= 400) {
errorhandler(xmlhttp.status + " Error deleting share: " + responseObj.error);
return false;
} else {
if (xmlhttp.responseText && xmlhttp.responseText != "") {
try {
var responseObj = JSON.parse(xmlhttp.responseText);
if (responseObj.error) {
Mojo.Log.error("Share service returned error: " + responseObj.error);
if (callback) {
callback(xmlhttp.responseText);
return false;
} else {
Mojo.Controller.getAppController().showBanner({ messageText: "Error deleting share: " + responseObj.error }, "", "");
}
errorhandler("Error deleting share: " + responseObj.error);
return false;
} else {
//Mojo.Log.info("Share List success! " + xmlhttp.responseText);
//Mojo.Log.info("Share Delete success! " + xmlhttp.responseText);
if (callback) {
callback(xmlhttp.responseText);
} else {
@@ -263,15 +235,13 @@ ShareServiceModel.prototype.DoShareDeleteRequest = function(itemid, username, cr
return true;
}
} catch (ex) {
Mojo.Controller.getAppController().showBanner({ messageText: "Error deleting share: server response malformed" }, "", "");
Mojo.Log.error("Share service response could not be parsed, error was: " + ex + ", response: " + xmlhttp.responseText);
errorhandler("Error parsing Share delete response: " + ex);
return false;
}
} else {
Mojo.Controller.getAppController().showBanner({ messageText: "Error deleting share: server response empty" }, "", "");
Mojo.Log.error("Share service delete response was empty: " + xmlhttp.responseText);
errorhandler("Delete Share response was empty");
return false;
}
if (callback) callback(false);
return false;
}
}
}.bind(this);
@@ -316,7 +286,7 @@ ShareServiceModel.prototype.GetRandomWords = function(callback) {
}
//HTTP request for new user
ShareServiceModel.prototype.DoNewUserRequest = function(username, sharephrase, password, callback) {
ShareServiceModel.prototype.DoNewUserRequest = function(username, sharephrase, password, callback, errorhandler) {
var useURL = this.buildURL(null, "new-user");
Mojo.Log.info("Creating user: " + username + " with share-phrase " + sharephrase + " and password " + password + " from URL " + useURL);
@@ -336,10 +306,8 @@ ShareServiceModel.prototype.DoNewUserRequest = function(username, sharephrase, p
xmlhttp.send(JSON.stringify(request));
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == XMLHttpRequest.DONE) {
if (xmlhttp.status == 404) {
Mojo.Log.error("Share service returned 404 creating user. If the service is online, there's probably a version mismatch between service and client.");
Mojo.Controller.getAppController().showBanner({ messageText: "Error sharing: 404 at endpoint" }, "", "");
if (callback) callback(false);
if (xmlhttp.status >= 400) {
errorhandler(xmlhttp.status + " Error creating user: " + responseObj.error);
return false;
} else {
Mojo.Log.info("Share service sent response while creating user: " + xmlhttp.responseText);
@@ -347,12 +315,8 @@ ShareServiceModel.prototype.DoNewUserRequest = function(username, sharephrase, p
try {
var responseObj = JSON.parse(xmlhttp.responseText);
if (responseObj.error) {
Mojo.Log.error("Share service returned error creating user: " + responseObj.error);
if (callback) {
callback(xmlhttp.responseText);
} else {
Mojo.Controller.getAppController().showBanner({ messageText: "Error creating user: " + responseObj.error }, "", "");
}
errorhandler("Error creating user: " + responseObj.error);
return false;
} else {
Mojo.Log.info("New user success! " + xmlhttp.responseText);
if (callback) {
@@ -363,15 +327,13 @@ ShareServiceModel.prototype.DoNewUserRequest = function(username, sharephrase, p
return true;
}
} catch (ex) {
Mojo.Controller.getAppController().showBanner({ messageText: "Error creating user: server response malformed" }, "", "");
Mojo.Log.error("Share service response could not be parsed, error was: " + ex + ", response: " + xmlhttp.responseText);
errorhandler("Error parsing create user response: " + ex);
return false;
}
} else {
Mojo.Controller.getAppController().showBanner({ messageText: "Error sharing: server response empty" }, "", "");
Mojo.Log.error("Share service response was empty: " + xmlhttp.responseText);
errorhandler("Create user response was empty");
return false;
}
if (callback) callback(false);
return false;
}
}
}.bind(this);
-7
View File
@@ -23,13 +23,6 @@
</div>
</div>
<div class="palm-group" id="addressError" style="display:none" name="addressError">
<div class="palm-group-title"><span style="color:white">Error</span></div>
<div class="errorresponse">
The Service end point is not reachable, not responding, or is not valid.
</div>
</div>
<div class="palm-dialog-buttons">
<div x-mojo-element="Button" id="goButton"></div>
<div x-mojo-element="Button" id="cancelButton"></div>