Skip to content

Commit 6748ecb

Browse files
committed
handle MissingRequiredFieldError exception (code 135)
1 parent 46466df commit 6748ecb

File tree

3 files changed

+68
-22
lines changed

3 files changed

+68
-22
lines changed

Parse/src/main/java/com/parse/ParseException.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,11 @@ public class ParseException extends Exception {
140140
*/
141141
public static final int INVALID_EMAIL_ADDRESS = 125;
142142

143+
/**
144+
* Error code indicating that required field is missing.
145+
*/
146+
public static final int MISSING_REQUIRED_FIELD_ERROR = 135;
147+
143148
/**
144149
* Error code indicating that a unique field was given a value that is already taken.
145150
*/

Parse/src/main/java/com/parse/ParseInstallation.java

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,13 +149,16 @@ public Task<T> then(Task<Void> task) throws Exception {
149149
@Override
150150
public Task<Void> then(Task<Void> task) throws Exception {
151151
// Retry the fetch as a save operation because this Installation was deleted on the server.
152-
if(task.getError() != null
153-
&& task.getError() instanceof ParseException
154-
&& ((ParseException) task.getError()).getCode() == ParseException.OBJECT_NOT_FOUND) {
155-
synchronized (mutex) {
156-
setState(new State.Builder(getState()).objectId(null).build());
157-
markAllFieldsDirty();
158-
return ParseInstallation.super.saveAsync(sessionToken, toAwait);
152+
if (task.getError() != null
153+
&& task.getError() instanceof ParseException) {
154+
int errCode = ((ParseException) task.getError()).getCode();
155+
if (errCode == ParseException.OBJECT_NOT_FOUND
156+
|| (errCode == ParseException.MISSING_REQUIRED_FIELD_ERROR && getObjectId() == null)) {
157+
synchronized (mutex) {
158+
setState(new State.Builder(getState()).objectId(null).build());
159+
markAllFieldsDirty();
160+
return ParseInstallation.super.saveAsync(sessionToken, toAwait);
161+
}
159162
}
160163
}
161164
return task;

Parse/src/test/java/com/parse/ParseInstallationTest.java

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -125,29 +125,48 @@ public void testInstallationObjectIdCannotBeChanged() throws Exception {
125125
}
126126

127127
@Test
128-
public void testSaveAsync() throws Exception {
129-
OfflineStore lds = new OfflineStore(RuntimeEnvironment.application);
130-
Parse.setLocalDatastore(lds);
131-
128+
public void testMissingRequiredFieldWhenSaveAsync() throws Exception {
132129
String sessionToken = "sessionToken";
133130
Task<Void> toAwait = Task.forResult(null);
134131

135-
ParseCurrentInstallationController controller =
136-
mock(ParseCurrentInstallationController.class);
137-
ParseInstallation currentInstallation = new ParseInstallation();
138-
when(controller.getAsync())
139-
.thenReturn(Task.forResult(currentInstallation));
132+
ParseCurrentInstallationController controller = mockCurrentInstallationController();
133+
134+
ParseObjectController objController = mock(ParseObjectController.class);
135+
// mock return task when Installation was deleted on the server
136+
Task<ParseObject.State> taskError = Task.forError(new ParseException(ParseException.MISSING_REQUIRED_FIELD_ERROR, ""));
137+
// mock return task when Installation was re-saved to the server
138+
Task<ParseObject.State> task = Task.forResult(null);
139+
when(objController.saveAsync(
140+
any(ParseObject.State.class),
141+
any(ParseOperationSet.class),
142+
eq(sessionToken),
143+
any(ParseDecoder.class)))
144+
.thenReturn(taskError)
145+
.thenReturn(task);
140146
ParseCorePlugins.getInstance()
141-
.registerCurrentInstallationController(controller);
142-
ParseObject.State state = new ParseObject.State.Builder("_Installation")
143-
.objectId("oldId")
144-
.put("deviceToken", "deviceToken")
145-
.build();
147+
.registerObjectController(objController);
148+
146149
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
147150
assertNotNull(installation);
148-
installation.setState(state);
149151
installation.put("key", "value");
152+
installation.saveAsync(sessionToken, toAwait);
153+
verify(controller).getAsync();
154+
verify(objController, times(2)).saveAsync(
155+
any(ParseObject.State.class),
156+
any(ParseOperationSet.class),
157+
eq(sessionToken),
158+
any(ParseDecoder.class));
159+
}
150160

161+
@Test
162+
public void testObjectNotFoundWhenSaveAsync() throws Exception {
163+
OfflineStore lds = new OfflineStore(RuntimeEnvironment.application);
164+
Parse.setLocalDatastore(lds);
165+
166+
String sessionToken = "sessionToken";
167+
Task<Void> toAwait = Task.forResult(null);
168+
169+
ParseCurrentInstallationController controller = mockCurrentInstallationController();
151170
ParseObjectController objController = mock(ParseObjectController.class);
152171
// mock return task when Installation was deleted on the server
153172
Task<ParseObject.State> taskError = Task.forError(new ParseException(ParseException.OBJECT_NOT_FOUND, ""));
@@ -163,6 +182,14 @@ public void testSaveAsync() throws Exception {
163182
ParseCorePlugins.getInstance()
164183
.registerObjectController(objController);
165184

185+
ParseObject.State state = new ParseObject.State.Builder("_Installation")
186+
.objectId("oldId")
187+
.put("deviceToken", "deviceToken")
188+
.build();
189+
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
190+
assertNotNull(installation);
191+
installation.setState(state);
192+
installation.put("key", "value");
166193
installation.saveAsync(sessionToken, toAwait);
167194

168195
verify(controller).getAsync();
@@ -367,4 +394,15 @@ private static void mocksForUpdateBeforeSave() {
367394
when(plugins.applicationContext()).thenReturn(RuntimeEnvironment.application);
368395
ParsePlugins.set(plugins);
369396
}
397+
398+
private ParseCurrentInstallationController mockCurrentInstallationController() {
399+
ParseCurrentInstallationController controller =
400+
mock(ParseCurrentInstallationController.class);
401+
ParseInstallation currentInstallation = new ParseInstallation();
402+
when(controller.getAsync())
403+
.thenReturn(Task.forResult(currentInstallation));
404+
ParseCorePlugins.getInstance()
405+
.registerCurrentInstallationController(controller);
406+
return controller;
407+
}
370408
}

0 commit comments

Comments
 (0)