Skip to content

Commit c0995a7

Browse files
authored
Merge pull request #3 from wondrous-io/unswallow-subscribe-errors
Unswallow subscribe errors
2 parents d055f35 + 1f2d830 commit c0995a7

File tree

3 files changed

+66
-3
lines changed

3 files changed

+66
-3
lines changed

ParseLiveQuery/src/main/java/com/parse/LiveQueryException.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,23 @@ private LiveQueryException(String detailMessage) {
1010
super(detailMessage);
1111
}
1212

13+
private LiveQueryException(String detailMessage, Throwable cause) {
14+
super(detailMessage, cause);
15+
}
16+
17+
private LiveQueryException(Throwable cause) {
18+
super(cause);
19+
}
20+
21+
/**
22+
* An error that is reported when any other unknown {@link RuntimeException} occurs unexpectedly.
23+
*/
24+
public static class UnknownException extends LiveQueryException {
25+
/* package */ UnknownException(String detailMessage, RuntimeException cause) {
26+
super(detailMessage, cause);
27+
}
28+
}
29+
1330
/**
1431
* An error that is reported when the server returns a response that cannot be parsed.
1532
*/

ParseLiveQuery/src/main/java/com/parse/ParseLiveQueryClientImpl.java

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -222,11 +222,26 @@ private Subscription<T> subscriptionForRequestId(int requestId) {
222222
}
223223

224224
private void sendSubscription(final Subscription<T> subscription) {
225-
ParseUser.getCurrentSessionTokenAsync().onSuccessTask(new Continuation<String, Task<Void>>() {
225+
ParseUser.getCurrentSessionTokenAsync().onSuccess(new Continuation<String, Void>() {
226226
@Override
227-
public Task<Void> then(Task<String> task) throws Exception {
227+
public Void then(Task<String> task) throws Exception {
228228
String sessionToken = task.getResult();
229-
return sendOperationAsync(new SubscribeClientOperation<>(subscription.getRequestId(), subscription.getQueryState(), sessionToken));
229+
SubscribeClientOperation<T> op = new SubscribeClientOperation<>(subscription.getRequestId(), subscription.getQueryState(), sessionToken);
230+
231+
// dispatch errors
232+
sendOperationAsync(op).continueWith(new Continuation<Void, Void>() {
233+
public Void then(Task<Void> task) {
234+
Exception error = task.getError();
235+
if (error != null) {
236+
if (error instanceof RuntimeException) {
237+
subscription.didEncounter(new LiveQueryException.UnknownException(
238+
"Error when subscribing", (RuntimeException) error), subscription.getQuery());
239+
}
240+
}
241+
return null;
242+
}
243+
});
244+
return null;
230245
}
231246
});
232247
}

ParseLiveQuery/src/test/java/com/parse/TestParseLiveQueryClient.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,17 @@
1818
import bolts.Task;
1919

2020
import static junit.framework.Assert.assertEquals;
21+
import static junit.framework.Assert.assertNotNull;
2122
import static junit.framework.Assert.assertTrue;
2223
import static org.mockito.AdditionalMatchers.and;
2324
import static org.mockito.AdditionalMatchers.not;
2425
import static org.mockito.Matchers.any;
26+
import static org.mockito.Matchers.anyString;
2527
import static org.mockito.Matchers.anyBoolean;
2628
import static org.mockito.Matchers.contains;
2729
import static org.mockito.Matchers.eq;
2830
import static org.mockito.Mockito.mock;
31+
import static org.mockito.Mockito.never;
2932
import static org.mockito.Mockito.times;
3033
import static org.mockito.Mockito.verify;
3134
import static org.mockito.Mockito.when;
@@ -110,6 +113,34 @@ public void testUnsubscribeWhenSubscribedToCallback() throws Exception {
110113
verify(unsubscribeMockCallback, times(1)).onUnsubscribe(parseQuery);
111114
}
112115

116+
@Test
117+
public void testErrorWhileSubscribing() throws Exception {
118+
ParseQuery.State state = mock(ParseQuery.State.class);
119+
when(state.toJSON(any(ParseEncoder.class))).thenThrow(new RuntimeException("forced error"));
120+
121+
ParseQuery.State.Builder builder = mock(ParseQuery.State.Builder.class);
122+
when(builder.build()).thenReturn(state);
123+
ParseQuery query = mock(ParseQuery.class);
124+
when(query.getBuilder()).thenReturn(builder);
125+
126+
SubscriptionHandling handling = parseLiveQueryClient.subscribe(query);
127+
128+
SubscriptionHandling.HandleErrorCallback<ParseObject> errorMockCallback = mock(SubscriptionHandling.HandleErrorCallback.class);
129+
handling.handleError(errorMockCallback);
130+
131+
// Trigger a re-subscribe
132+
webSocketClientCallback.onMessage(createConnectedMessage().toString());
133+
134+
// This will never get a chance to call op=subscribe, because an exception was thrown
135+
verify(webSocketClient, never()).send(anyString());
136+
137+
ArgumentCaptor<LiveQueryException> errorCaptor = ArgumentCaptor.forClass(LiveQueryException.class);
138+
verify(errorMockCallback, times(1)).onError(eq(query), errorCaptor.capture());
139+
140+
assertEquals("Error when subscribing", errorCaptor.getValue().getMessage());
141+
assertNotNull(errorCaptor.getValue().getCause());
142+
}
143+
113144
@Test
114145
public void testErrorWhenSubscribedToCallback() throws Exception {
115146
ParseQuery<ParseObject> parseQuery = new ParseQuery<>("test");

0 commit comments

Comments
 (0)