From 36a0947902e5682e60edc9b7d0c9b2a1fa630dc1 Mon Sep 17 00:00:00 2001
From: Piotr Gawron <piotr.gawron@uni.lu>
Date: Wed, 5 Jun 2019 19:02:17 +0200
Subject: [PATCH] error reported to the frontend is more readable

---
 .../main/js/gui/admin/ConfigurationAdminPanel.js  | 15 ++++++++++++++-
 .../java/lcsb/mapviewer/api/BaseController.java   | 12 ++++++++----
 .../api/configuration/ConfigurationRestImpl.java  |  2 +-
 3 files changed, 23 insertions(+), 6 deletions(-)

diff --git a/frontend-js/src/main/js/gui/admin/ConfigurationAdminPanel.js b/frontend-js/src/main/js/gui/admin/ConfigurationAdminPanel.js
index c2357d11fc..7c7fe4c9cd 100644
--- a/frontend-js/src/main/js/gui/admin/ConfigurationAdminPanel.js
+++ b/frontend-js/src/main/js/gui/admin/ConfigurationAdminPanel.js
@@ -6,9 +6,11 @@ var ConfigurationType = require('../../ConfigurationType');
 
 var Functions = require('../../Functions');
 var GuiConnector = require('../../GuiConnector');
+var NetworkError = require('../../NetworkError');
 var ValidationError = require('../../ValidationError');
 
 var logger = require('../../logger');
+var HttpStatus = require('http-status-codes');
 
 var Promise = require("bluebird");
 var xss = require("xss");
@@ -253,9 +255,11 @@ ConfigurationAdminPanel.prototype.saveOption = function (type) {
     value = element.val();
   }
 
+  var oldVal;
   GuiConnector.showProcessing();
   return self.getServerConnector().getConfiguration().then(function (configuration) {
     option = configuration.getOption(type);
+    oldVal = option.getValue();
     if (option === undefined) {
       return Promise.reject(new ValidationError("Unknown configuration type: " + type));
     }
@@ -317,7 +321,16 @@ ConfigurationAdminPanel.prototype.saveOption = function (type) {
         }
       });
     }
-  }).catch(GuiConnector.alert).finally(GuiConnector.hideProcessing);
+  }).catch(function (e) {
+    if (e instanceof NetworkError && e.statusCode === HttpStatus.BAD_REQUEST) {
+      var content = e.content;
+      GuiConnector.alert(new ValidationError(content.reason));
+      option.setValue(oldVal);
+      element.val(oldVal);
+    } else {
+      GuiConnector.alert(e);
+    }
+  }).finally(GuiConnector.hideProcessing);
 };
 
 /**
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java b/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java
index 7bc7a6182d..68c9d13003 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/BaseController.java
@@ -3,8 +3,9 @@ package lcsb.mapviewer.api;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.net.URLDecoder;
-import java.util.TreeMap;
+import java.util.HashMap;
 import java.util.Map;
+import java.util.TreeMap;
 
 import org.apache.log4j.Logger;
 import org.springframework.http.HttpHeaders;
@@ -37,7 +38,8 @@ public abstract class BaseController {
     } else if (e instanceof ObjectExistsException) {
       return createErrorResponse("Object already exists.", e.getMessage(), new HttpHeaders(), HttpStatus.CONFLICT);
     } else if (e instanceof OperationNotAllowedException) {
-      return createErrorResponse("Operation not allowed.", e.getMessage(), new HttpHeaders(), HttpStatus.METHOD_NOT_ALLOWED);
+      return createErrorResponse("Operation not allowed.", e.getMessage(), new HttpHeaders(),
+          HttpStatus.METHOD_NOT_ALLOWED);
     } else if (e instanceof QueryException) {
       logger.error(e, e);
       return createErrorResponse("Query server error.", e.getMessage(), new HttpHeaders(), HttpStatus.BAD_REQUEST);
@@ -53,8 +55,10 @@ public abstract class BaseController {
   private ResponseEntity<Object> createErrorResponse(String errorMessage, String error, HttpHeaders httpHeaders,
       HttpStatus status) {
 
-    return new ResponseEntity<Object>(
-        "{\"error\" : \"" + errorMessage + "\",\"reason\":" + new Gson().toJson(error) + "}", httpHeaders, status);
+    Map<String, String> response = new HashMap<>();
+    response.put("error", errorMessage);
+    response.put("reason", error);
+    return new ResponseEntity<Object>(new Gson().toJson(response), httpHeaders, status);
   }
 
   public Map<String, Object> parseBody(String body) throws IOException, JsonParseException, JsonMappingException {
diff --git a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java
index 326e146520..e956cad4a2 100644
--- a/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java
+++ b/rest-api/src/main/java/lcsb/mapviewer/api/configuration/ConfigurationRestImpl.java
@@ -293,7 +293,7 @@ public class ConfigurationRestImpl extends BaseRestImpl {
     try {
       configurationService.setConfigurationValue(type, value);
     } catch (InvalidArgumentException e) {
-      throw new QueryException(e);
+      throw new QueryException(e.getMessage(), e);
     }
     return optionToMap(configurationService.getValue(type));
   }
-- 
GitLab