Check for broken JSON responses from remote server

Change-Id: Id4b1994400ff72f36cf545fc5daf87a57e622c15
diff --git a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java
index 783fda9..b81bc51 100644
--- a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java
+++ b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/IdsExportService.java
@@ -224,7 +224,17 @@
         };
         
         // Initialize exporter (with meta data and first matches)
-        exp.init(resp);
+        try {
+            exp.init(resp);
+        } catch (Exception e) {
+
+            throw new WebApplicationException(
+                responseForm(
+                    Status.INTERNAL_SERVER_ERROR,
+                    e.getMessage()
+                    )
+                );
+        }
 
         // If only one page should be exported there is no need
         // for a temporary export file
@@ -256,16 +266,26 @@
 
             uri.queryParam("offset", "{offset}");
 
-            // Iterate over all results
-            for (int i = 2; i <= pg; i++) {
-                resource = client.target(
-                    uri.build((i * pageSize) - pageSize)
+            try {
+            
+                // Iterate over all results
+                for (int i = 2; i <= pg; i++) {
+                    resource = client.target(
+                        uri.build((i * pageSize) - pageSize)
+                        );
+               
+                    reqBuilder = resource.request(MediaType.APPLICATION_JSON);
+                    resp = authBuilder(reqBuilder, xff, auth).get(String.class);
+                    exp.appendMatches(resp);
+                }
+            } catch (Exception e) {
+                throw new WebApplicationException(
+                    responseForm(
+                        Status.INTERNAL_SERVER_ERROR,
+                        e.getMessage()
+                        )
                     );
-
-                reqBuilder = resource.request(MediaType.APPLICATION_JSON);
-                resp = authBuilder(reqBuilder, xff, auth).get(String.class);
-                exp.appendMatches(resp);
-            }
+            };
 
             builder = exp.serve();
         };        
diff --git a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/MatchAggregator.java b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/MatchAggregator.java
index 76503b5..1bf61b7 100644
--- a/plugin/src/main/java/de/ids_mannheim/korap/plkexport/MatchAggregator.java
+++ b/plugin/src/main/java/de/ids_mannheim/korap/plkexport/MatchAggregator.java
@@ -16,6 +16,7 @@
 import com.fasterxml.jackson.core.JsonFactory;
 import com.fasterxml.jackson.core.JsonParser;
 import com.fasterxml.jackson.core.Version;
+import com.fasterxml.jackson.core.JsonParseException;
 import com.fasterxml.jackson.databind.JsonNode;
 import com.fasterxml.jackson.databind.ObjectMapper;
 
@@ -112,7 +113,7 @@
      * Create new match aggregator and parse initial Json
      * file to get header information and initial matches.
      */
-    public void init (String resp) throws IOException {
+    public void init (String resp) throws IOException, JsonParseException {
 
         this.file = null;
 
@@ -123,7 +124,7 @@
         
         JsonParser parser = mapper.getFactory().createParser(resp);
         JsonNode actualObj = mapper.readTree(parser);
-
+        
         if (actualObj == null)
             return;
 
diff --git a/plugin/src/test/java/de/ids_mannheim/korap/plkexport/IdsExportServiceTest.java b/plugin/src/test/java/de/ids_mannheim/korap/plkexport/IdsExportServiceTest.java
index 1f52592..f4c237a 100644
--- a/plugin/src/test/java/de/ids_mannheim/korap/plkexport/IdsExportServiceTest.java
+++ b/plugin/src/test/java/de/ids_mannheim/korap/plkexport/IdsExportServiceTest.java
@@ -336,6 +336,83 @@
         String str = responsertf.readEntity(String.class);
 
         assertTrue("Corpus info", str.contains("{\\pard Corpus: \\f1 corpusSigle = \"WPD17\"\\par}"));
+        assertFalse("Errors", str.contains("dynCall("));
+    }
+
+    @Test
+    public void testExportWsRTFbroken () {
+        mockClient.reset().when(
+            request()
+            .withMethod("GET")
+            .withPath("/api/v1.0/search")
+            )
+            .respond(
+                response()
+                .withHeader("Content-Type: application/json; charset=utf-8")
+                .withBody(getFixture("response_broken.json"))
+                .withStatusCode(200)
+                );
+
+        MultivaluedHashMap<String, String> frmap = new MultivaluedHashMap<String, String>();
+        frmap.add("format", "rtf");
+        frmap.add("q", "???");
+        frmap.add("ql", "poliqarp");
+        frmap.add("cq", "corpusSigle = \"WPD17\"");
+        frmap.add("cutoff", "true");
+        String filenamer = "dateiRtf";
+        frmap.putSingle("fname", filenamer);
+
+        Response responsertf = target("/export").request()
+            .post(Entity.form(frmap));
+        assertEquals("Request RTF: Http Response should be 500: ",
+                500, responsertf.getStatus());
+        String str = responsertf.readEntity(String.class);
+
+        assertTrue("Title", str.contains("<title>Export</title>"));
+        assertTrue("Error", str.contains("line: 1, column: 539"));
+
+        // Check paging with broken second page
+        mockClient.reset().when(
+            request()
+            .withMethod("GET")
+            .withPath("/api/v1.0/search")
+            .withQueryStringParameter("q", "Plagegeist")
+            .withQueryStringParameter("count", "5")
+            .withQueryStringParameter("offset", "5")
+            )
+            .respond(
+                response()
+                .withHeader("Content-Type: application/json; charset=utf-8")
+                .withBody(getFixture("response_broken.json"))
+                .withStatusCode(200)
+                );
+
+        mockClient.when(
+            request()
+            .withMethod("GET")
+            .withPath("/api/v1.0/search")
+            .withQueryStringParameter("q", "Plagegeist")
+            )
+            .respond(
+                response()
+                .withHeader("Content-Type: application/json; charset=utf-8")
+                .withBody(getFixture("response_plagegeist_1.json"))
+                .withStatusCode(200)
+                );
+        frmap = new MultivaluedHashMap<String, String>();
+        frmap.add("format", "rtf");
+        frmap.add("q", "Plagegeist");
+        frmap.add("ql", "poliqarp");
+        frmap.putSingle("fname", filenamer);
+
+        responsertf = target("/export").request()
+            .post(Entity.form(frmap));
+        assertEquals("Request RTF: Http Response should be 500: ",
+                500, responsertf.getStatus());
+
+        str = responsertf.readEntity(String.class);
+        assertTrue("Title", str.contains("<title>Export</title>"));
+        assertTrue("Error", str.contains("line: 1, column: 539"));
     }
     
 
diff --git a/plugin/src/test/resources/fixtures/response_broken.json b/plugin/src/test/resources/fixtures/response_broken.json
new file mode 100644
index 0000000..97e48b3
--- /dev/null
+++ b/plugin/src/test/resources/fixtures/response_broken.json
@@ -0,0 +1 @@
+{"@context":"http://korap.ids-mannheim.de/ns/KoralQuery/v0.3/context.jsonld","meta":{"cutOff":false,"count":5,"startIndex":0,"timeout":10000,"context":{"left":["token",40],"right":["token",40]},"fields":["ID","UID","textSigle","corpusID","author","title","subTitle","te