diff --git a/frontend-js/src/main/js/GuiConnector.js b/frontend-js/src/main/js/GuiConnector.js index 007cd26a656eb80cdf9cba725e1f46561a968dcd..8681ba981c91018e37b13498b62495fd227db782 100644 --- a/frontend-js/src/main/js/GuiConnector.js +++ b/frontend-js/src/main/js/GuiConnector.js @@ -264,6 +264,37 @@ GuiConnector.prototype.hideProcessing = function () { $(self._processingDialog).dialog("close"); }; +GuiConnector.prototype.showErrorDialog = function (title, content) { + var dialog = document.createElement('div'); + dialog.title = title; + var dialogBody = document.createElement('p'); + dialogBody.innerHTML = content; + dialog.appendChild(dialogBody); + $(dialog).dialog({ + modal: true, + classes: { + "ui-dialog": "ui-state-error" + }, + close: function () { + $(this).dialog('destroy').remove(); + } + }).siblings('.ui-dialog-titlebar').css("background", "red"); +}; + +GuiConnector.prototype.showSuccessDialog = function (title, content) { + var dialog = document.createElement('div'); + dialog.title = title; + var dialogBody = document.createElement('p'); + dialogBody.innerHTML = content; + dialog.appendChild(dialogBody); + $(dialog).dialog({ + modal: true, + close: function () { + $(this).dialog('destroy').remove(); + } + }).siblings('.ui-dialog-titlebar').css("background", "green"); +}; + /** * Gather information that are presented to the user before submission to MinervaNet. * @@ -303,31 +334,15 @@ GuiConnector.prototype.gatherReportData = function () { * @param {boolean} [redirectIfSecurityError] */ GuiConnector.prototype.alert = function (error, redirectIfSecurityError) { + error = error || ''; if (redirectIfSecurityError && error instanceof SecurityError && ServerConnector.getSessionData().getLogin() === "anonymous") { window.location.href = ServerConnector.getServerBaseUrl() + "login.xhtml?from=" + encodeURI(window.location.href); } else { var self = returnThisOrSingleton(this); logger.error(error); - var errorData = self.getErrorMessageForError(error); if (!errorData.showReport) { - // legacy dialog (no report) - self._errorDialog = document.createElement("div"); - self._errorDialogContent = document.createElement("div"); - self._errorDialog.appendChild(self._errorDialogContent); - document.body.appendChild(self._errorDialog); - $(self._errorDialog).dialog({ - classes: { - "ui-dialog": "ui-state-error" - }, - modal: true, - title: "ERROR", - close: function () { - $(this).dialog('destroy').remove(); - } - }).siblings('.ui-dialog-titlebar').css("background", "red"); - self._errorDialogContent.innerHTML = errorData.message; - $(self._errorDialog).dialog("open"); + self.showErrorDialog("An error occurred!", errorData.message); } else { self._errorDialog = document.createElement('div'); self._errorDialog.innerHTML = '<span class="ui-icon ui-icon-info" style="float: right;" title="The error message. This might not be human readable. If this issue persists you should should contact your administrator."></span>' + @@ -396,14 +411,22 @@ GuiConnector.prototype.alert = function (error, redirectIfSecurityError) { report[check.attr('data-key')] = check.attr('data-value'); } }); - ServerConnector.submitErrorToMinervaNet(report); - $(this).dialog('close'); + ServerConnector.submitErrorToMinervaNet(report, function (error, response) { + if (error || response.statusCode !== 200) { + self.showErrorDialog('Report could not be submitted!', + 'Please contact your system administrator if this issue persists.'); + } else { + self.showSuccessDialog('Report has been submitted!', + 'Thank you very much for helping us to improve Minerva.'); + } + }); + $(this).dialog('destroy').remove(); }, 'Cancel': function () { - $(this).dialog('close'); + $(this).dialog('destroy').remove(); } } - }).dialog("open").siblings('.ui-dialog-titlebar').css("background", "red"); + }).siblings('.ui-dialog-titlebar').css("background", "red"); } } }; diff --git a/frontend-js/src/main/js/ServerConnector.js b/frontend-js/src/main/js/ServerConnector.js index 77514d3eb81b1a8427954c02d3245724640b0736..cbec64df630dabda7c62ed3c8ce9575992e57e40 100644 --- a/frontend-js/src/main/js/ServerConnector.js +++ b/frontend-js/src/main/js/ServerConnector.js @@ -2683,7 +2683,7 @@ ServerConnector.getSubmapConnections = function () { }); }; -ServerConnector.submitErrorToMinervaNet = function (report) { +ServerConnector.submitErrorToMinervaNet = function (report, callback) { var self = this; return request(self.getSubmitErrorToMinervaNetUrl(), { method: 'POST', @@ -2691,7 +2691,7 @@ ServerConnector.submitErrorToMinervaNet = function (report) { 'Content-type': 'application/json' }, body: JSON.stringify(report) - }); + }, callback); }; diff --git a/frontend-js/src/test/js/GuiConnector-test.js b/frontend-js/src/test/js/GuiConnector-test.js index fa04c5f3f7f7bad3e7310fdf8aeb88707ee31072..ff313d564ace3c4c995938565413514f466356cc 100644 --- a/frontend-js/src/test/js/GuiConnector-test.js +++ b/frontend-js/src/test/js/GuiConnector-test.js @@ -34,7 +34,9 @@ describe('GuiConnector', function () { var connector = new (GuiConnector.constructor)(); connector.alert("some error"); $(".ui-dialog-content").each(function () { - assert.ok($(this).dialog('isOpen')); + var dialog = $(this); + assert.ok(dialog.dialog('isOpen')); + dialog.dialog('close').remove(); }); connector.destroy(); }); diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/minervanet/MinervaNetController.java b/rest-api/src/main/java/lcsb/mapviewer/api/minervanet/MinervaNetController.java index 345b90e7a9295a478ffe96e5a56364acea066095..ed0b054a9da14866e0f2d5adb08efe8a65baef25 100644 --- a/rest-api/src/main/java/lcsb/mapviewer/api/minervanet/MinervaNetController.java +++ b/rest-api/src/main/java/lcsb/mapviewer/api/minervanet/MinervaNetController.java @@ -1,5 +1,6 @@ package lcsb.mapviewer.api.minervanet; +import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import lcsb.mapviewer.model.user.ConfigurationElementType; import lcsb.mapviewer.services.interfaces.IConfigurationService; @@ -50,11 +51,24 @@ public class MinervaNetController { try (CloseableHttpResponse response = client.execute(post)) { HttpEntity responseEntity = response.getEntity(); String responseBody = EntityUtils.toString(responseEntity, "UTF-8"); - if (response.getStatusLine().getStatusCode() != 200) { - logger.error("Could not submit report to MinervaNet. Reason: " + responseBody); + if (response.getStatusLine().getStatusCode() != 200 || !responseBodyValid(responseBody)) { + String error = "Could not submit report to MinervaNet. Reason: " + responseBody; + logger.error(error); + throw new ReportSubmissionException(error); } } } } + private boolean responseBodyValid(String body) { + ObjectMapper mapper = new ObjectMapper(); + mapper.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY); + try { + mapper.readTree(body); + } catch (IOException e) { + return false; + } + return true; + } + } diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/minervanet/ReportSubmissionException.java b/rest-api/src/main/java/lcsb/mapviewer/api/minervanet/ReportSubmissionException.java new file mode 100644 index 0000000000000000000000000000000000000000..38f567524a172cc88d903d09373b063d79ea388e --- /dev/null +++ b/rest-api/src/main/java/lcsb/mapviewer/api/minervanet/ReportSubmissionException.java @@ -0,0 +1,23 @@ +package lcsb.mapviewer.api.minervanet; + +public class ReportSubmissionException extends RuntimeException { + public ReportSubmissionException() { + super(); + } + + public ReportSubmissionException(String message) { + super(message); + } + + public ReportSubmissionException(String message, Throwable cause) { + super(message, cause); + } + + public ReportSubmissionException(Throwable cause) { + super(cause); + } + + protected ReportSubmissionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +}