Skip to content

Commit 9fda93e

Browse files
author
DvirDukhan
authored
Merge pull request #49 from RedisGraph/runtime-error-handling
Catch run-time and compile-time server exceptions
2 parents 42f4766 + c61a5eb commit 9fda93e

File tree

6 files changed

+186
-9
lines changed

6 files changed

+186
-9
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.redislabs.redisgraph.exceptions;
2+
3+
import redis.clients.jedis.exceptions.JedisDataException;
4+
5+
/**
6+
* RedisGraph query syntax evaluation exception. An instance of JRedisGraphRunTimeException is thrown when RedisGraph
7+
* encounters an error during query syntax evaluation.
8+
*/
9+
public class JRedisGraphCompileTimeException extends JedisDataException {
10+
public JRedisGraphCompileTimeException(String message) {
11+
super(message);
12+
}
13+
14+
public JRedisGraphCompileTimeException(Throwable cause) {
15+
super(cause);
16+
}
17+
18+
public JRedisGraphCompileTimeException(String message, Throwable cause) {
19+
super(message, cause);
20+
}
21+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.redislabs.redisgraph.exceptions;
2+
3+
import redis.clients.jedis.exceptions.JedisDataException;
4+
5+
/**
6+
* RedisGraph runtime exception. An instance of JRedisGraphRunTimeException is thrown when RedisGraph
7+
* encounters a runtime error during query execution.
8+
*/
9+
public class JRedisGraphRunTimeException extends JedisDataException {
10+
public JRedisGraphRunTimeException(String message) {
11+
super(message);
12+
}
13+
14+
public JRedisGraphRunTimeException(Throwable cause) {
15+
super(cause);
16+
}
17+
18+
public JRedisGraphRunTimeException(String message, Throwable cause) {
19+
super(message, cause);
20+
}
21+
}

src/main/java/com/redislabs/redisgraph/impl/api/ContextedRedisGraph.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22

33
import com.redislabs.redisgraph.RedisGraphContext;
44
import com.redislabs.redisgraph.ResultSet;
5+
import com.redislabs.redisgraph.exceptions.JRedisGraphCompileTimeException;
6+
import com.redislabs.redisgraph.exceptions.JRedisGraphRunTimeException;
57
import com.redislabs.redisgraph.impl.Utils;
68
import com.redislabs.redisgraph.impl.graph_cache.RedisGraphCaches;
79
import com.redislabs.redisgraph.impl.resultset.ResultSetImpl;
810
import redis.clients.jedis.Client;
911
import redis.clients.jedis.Jedis;
1012
import redis.clients.jedis.util.SafeEncoder;
11-
13+
import redis.clients.jedis.exceptions.JedisDataException;
1214
import java.util.List;
1315

1416
/**
15-
* An implementaion of RedisGraphContext. Allows sending RedisGraph and some Redis commands,
17+
* An implementation of RedisGraphContext. Allows sending RedisGraph and some Redis commands,
1618
* within a specific connection context
1719
*/
1820
public class ContextedRedisGraph extends AbstractRedisGraph implements RedisGraphContext, RedisGraphCacheHolder {
@@ -50,9 +52,11 @@ protected ResultSet sendQuery(String graphId, String preparedQuery) {
5052
List<Object> rawResponse = (List<Object>) conn.sendCommand(RedisGraphCommand.QUERY, graphId, preparedQuery, Utils.COMPACT_STRING);
5153
return new ResultSetImpl(rawResponse, this, caches.getGraphCache(graphId));
5254
}
53-
catch (Exception e) {
54-
conn.close();
55-
throw e;
55+
catch (JRedisGraphRunTimeException rt) {
56+
throw rt;
57+
}
58+
catch (JedisDataException j) {
59+
throw new JRedisGraphCompileTimeException(j);
5660
}
5761
}
5862

src/main/java/com/redislabs/redisgraph/impl/resultset/ResultSetImpl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,14 @@
55
import com.redislabs.redisgraph.RedisGraph;
66
import com.redislabs.redisgraph.ResultSet;
77
import com.redislabs.redisgraph.Statistics;
8+
import com.redislabs.redisgraph.exceptions.JRedisGraphRunTimeException;
89
import com.redislabs.redisgraph.graph_entities.Edge;
910
import com.redislabs.redisgraph.graph_entities.GraphEntity;
1011
import com.redislabs.redisgraph.graph_entities.Node;
1112
import com.redislabs.redisgraph.graph_entities.Property;
1213
import com.redislabs.redisgraph.impl.graph_cache.GraphCache;
1314
import redis.clients.jedis.util.SafeEncoder;
15+
import redis.clients.jedis.exceptions.JedisDataException;
1416

1517
import java.util.ArrayList;
1618
import java.util.List;
@@ -35,6 +37,13 @@ public class ResultSetImpl implements ResultSet {
3537
public ResultSetImpl(List<Object> rawResponse, RedisGraph redisGraph, GraphCache cache) {
3638
this.redisGraph = redisGraph;
3739
this.cache = cache;
40+
41+
// If a run-time error occured, the last member of the rawResponse will be a JedisDataException.
42+
if (rawResponse.get(rawResponse.size()-1) instanceof JedisDataException) {
43+
44+
throw new JRedisGraphRunTimeException((Throwable) rawResponse.get(rawResponse.size() - 1));
45+
}
46+
3847
if (rawResponse.size() != 3) {
3948

4049
header = parseHeader(new ArrayList<>());

src/test/java/com/redislabs/redisgraph/RedisGraphAPITest.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -584,10 +584,6 @@ public void testMultiExec(){
584584
Assert.assertEquals(Arrays.asList("n"), record.keys());
585585
Assert.assertEquals(expectedNode, record.getValue("n"));
586586

587-
// Graph delete
588-
Assert.assertTrue(((String)results.get(6)).startsWith("Graph removed"));
589-
590-
591587
Assert.assertEquals(ResultSetImpl.class, results.get(7).getClass());
592588
resultSet = (ResultSet) results.get(7);
593589

@@ -881,4 +877,5 @@ record = resultSet.next();
881877
}
882878

883879
}
880+
884881
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
package com.redislabs.redisgraph.exceptions;
2+
3+
import com.redislabs.redisgraph.RedisGraphContext;
4+
import com.redislabs.redisgraph.RedisGraphContextGenerator;
5+
import com.redislabs.redisgraph.impl.api.RedisGraph;
6+
import org.junit.After;
7+
import org.junit.Assert;
8+
import org.junit.Before;
9+
import org.junit.Rule;
10+
import org.junit.Test;
11+
import org.junit.rules.ExpectedException;
12+
13+
14+
public class JRedisGraphErrorTest {
15+
16+
private RedisGraphContextGenerator api;
17+
18+
@Before
19+
public void createApi(){
20+
api = new RedisGraph();
21+
Assert.assertNotNull(api.query("social", "CREATE (:person{mixed_prop: 'strval'}), (:person{mixed_prop: 50})"));
22+
}
23+
@After
24+
public void deleteGraph() {
25+
26+
api.deleteGraph("social");
27+
api.close();
28+
}
29+
30+
@Rule
31+
public ExpectedException exceptionRule = ExpectedException.none();
32+
33+
@Test
34+
public void testSyntaxErrorReporting() {
35+
exceptionRule.expect(JRedisGraphCompileTimeException.class);
36+
exceptionRule.expectMessage("Type mismatch: expected String but was Integer");
37+
38+
// Issue a query that causes a compile-time error
39+
api.query("social", "RETURN toUpper(5)");
40+
41+
}
42+
43+
@Test
44+
public void testRuntimeErrorReporting() {
45+
exceptionRule.expect(JRedisGraphRunTimeException.class);
46+
exceptionRule.expectMessage("Type mismatch: expected String but was Integer");
47+
48+
// Issue a query that causes a run-time error
49+
api.query("social", "MATCH (p:person) RETURN toUpper(p.mixed_prop)");
50+
}
51+
52+
@Test
53+
public void testExceptionFlow() {
54+
55+
try {
56+
// Issue a query that causes a compile-time error
57+
api.query("social", "RETURN toUpper(5)");
58+
}
59+
catch (Exception e) {
60+
Assert.assertEquals(JRedisGraphCompileTimeException.class, e.getClass());
61+
Assert.assertTrue( e.getMessage().contains("Type mismatch: expected String but was Integer"));
62+
}
63+
64+
// On general api usage, user should get a new connection
65+
66+
try {
67+
// Issue a query that causes a compile-time error
68+
api.query("social", "MATCH (p:person) RETURN toUpper(p.mixed_prop)");
69+
}
70+
catch (Exception e) {
71+
Assert.assertEquals(JRedisGraphRunTimeException.class, e.getClass());
72+
Assert.assertTrue( e.getMessage().contains("Type mismatch: expected String but was Integer"));
73+
}
74+
75+
}
76+
77+
78+
@Test
79+
public void testContextSyntaxErrorReporting() {
80+
exceptionRule.expect(JRedisGraphCompileTimeException.class);
81+
exceptionRule.expectMessage("Type mismatch: expected String but was Integer");
82+
RedisGraphContext c = api.getContext();
83+
84+
// Issue a query that causes a compile-time error
85+
c.query("social", "RETURN toUpper(5)");
86+
87+
}
88+
89+
@Test
90+
public void testContextRuntimeErrorReporting() {
91+
exceptionRule.expect(JRedisGraphRunTimeException.class);
92+
exceptionRule.expectMessage("Type mismatch: expected String but was Integer");
93+
94+
RedisGraphContext c = api.getContext();
95+
// Issue a query that causes a run-time error
96+
c.query("social", "MATCH (p:person) RETURN toUpper(p.mixed_prop)");
97+
}
98+
99+
100+
@Test
101+
public void testContextExceptionFlow() {
102+
103+
RedisGraphContext c = api.getContext();
104+
try {
105+
// Issue a query that causes a compile-time error
106+
c.query("social", "RETURN toUpper(5)");
107+
}
108+
catch (Exception e) {
109+
Assert.assertEquals(JRedisGraphCompileTimeException.class, e.getClass());
110+
Assert.assertTrue( e.getMessage().contains("Type mismatch: expected String but was Integer"));
111+
}
112+
113+
// On contexted api usage, connection should stay open
114+
115+
try {
116+
// Issue a query that causes a compile-time error
117+
c.query("social", "MATCH (p:person) RETURN toUpper(p.mixed_prop)");
118+
}
119+
catch (Exception e) {
120+
Assert.assertEquals(JRedisGraphRunTimeException.class, e.getClass());
121+
Assert.assertTrue( e.getMessage().contains("Type mismatch: expected String but was Integer"));
122+
}
123+
124+
}
125+
}

0 commit comments

Comments
 (0)