Skip to content

Commit 8a314f6

Browse files
committed
handle MissingRequiredFieldError exception (code 135)
1 parent 2ab94e5 commit 8a314f6

File tree

3 files changed

+68
-22
lines changed

3 files changed

+68
-22
lines changed

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

+5
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,11 @@ public class ParseException extends Exception {
134134
*/
135135
public static final int INVALID_EMAIL_ADDRESS = 125;
136136

137+
/**
138+
* Error code indicating that required field is missing.
139+
*/
140+
public static final int MISSING_REQUIRED_FIELD_ERROR = 135;
141+
137142
/**
138143
* Error code indicating that a unique field was given a value that is already taken.
139144
*/

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

+10-7
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

+53-15
Original file line numberDiff line numberDiff line change
@@ -121,29 +121,48 @@ public void testInstallationObjectIdCannotBeChanged() throws Exception {
121121
}
122122

123123
@Test
124-
public void testSaveAsync() throws Exception {
125-
OfflineStore lds = new OfflineStore(RuntimeEnvironment.application);
126-
Parse.setLocalDatastore(lds);
127-
124+
public void testMissingRequiredFieldWhenSaveAsync() throws Exception {
128125
String sessionToken = "sessionToken";
129126
Task<Void> toAwait = Task.forResult(null);
130127

131-
ParseCurrentInstallationController controller =
132-
mock(ParseCurrentInstallationController.class);
133-
ParseInstallation currentInstallation = new ParseInstallation();
134-
when(controller.getAsync())
135-
.thenReturn(Task.forResult(currentInstallation));
128+
ParseCurrentInstallationController controller = mockCurrentInstallationController();
129+
130+
ParseObjectController objController = mock(ParseObjectController.class);
131+
// mock return task when Installation was deleted on the server
132+
Task<ParseObject.State> taskError = Task.forError(new ParseException(ParseException.MISSING_REQUIRED_FIELD_ERROR, ""));
133+
// mock return task when Installation was re-saved to the server
134+
Task<ParseObject.State> task = Task.forResult(null);
135+
when(objController.saveAsync(
136+
any(ParseObject.State.class),
137+
any(ParseOperationSet.class),
138+
eq(sessionToken),
139+
any(ParseDecoder.class)))
140+
.thenReturn(taskError)
141+
.thenReturn(task);
136142
ParseCorePlugins.getInstance()
137-
.registerCurrentInstallationController(controller);
138-
ParseObject.State state = new ParseObject.State.Builder("_Installation")
139-
.objectId("oldId")
140-
.put("deviceToken", "deviceToken")
141-
.build();
143+
.registerObjectController(objController);
144+
142145
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
143146
assertNotNull(installation);
144-
installation.setState(state);
145147
installation.put("key", "value");
148+
installation.saveAsync(sessionToken, toAwait);
149+
verify(controller).getAsync();
150+
verify(objController, times(2)).saveAsync(
151+
any(ParseObject.State.class),
152+
any(ParseOperationSet.class),
153+
eq(sessionToken),
154+
any(ParseDecoder.class));
155+
}
146156

157+
@Test
158+
public void testObjectNotFoundWhenSaveAsync() throws Exception {
159+
OfflineStore lds = new OfflineStore(RuntimeEnvironment.application);
160+
Parse.setLocalDatastore(lds);
161+
162+
String sessionToken = "sessionToken";
163+
Task<Void> toAwait = Task.forResult(null);
164+
165+
ParseCurrentInstallationController controller = mockCurrentInstallationController();
147166
ParseObjectController objController = mock(ParseObjectController.class);
148167
// mock return task when Installation was deleted on the server
149168
Task<ParseObject.State> taskError = Task.forError(new ParseException(ParseException.OBJECT_NOT_FOUND, ""));
@@ -159,6 +178,14 @@ public void testSaveAsync() throws Exception {
159178
ParseCorePlugins.getInstance()
160179
.registerObjectController(objController);
161180

181+
ParseObject.State state = new ParseObject.State.Builder("_Installation")
182+
.objectId("oldId")
183+
.put("deviceToken", "deviceToken")
184+
.build();
185+
ParseInstallation installation = ParseInstallation.getCurrentInstallation();
186+
assertNotNull(installation);
187+
installation.setState(state);
188+
installation.put("key", "value");
162189
installation.saveAsync(sessionToken, toAwait);
163190

164191
verify(controller).getAsync();
@@ -360,4 +387,15 @@ private static void mocksForUpdateBeforeSave() {
360387
when(plugins.applicationContext()).thenReturn(RuntimeEnvironment.application);
361388
ParsePlugins.set(plugins);
362389
}
390+
391+
private ParseCurrentInstallationController mockCurrentInstallationController() {
392+
ParseCurrentInstallationController controller =
393+
mock(ParseCurrentInstallationController.class);
394+
ParseInstallation currentInstallation = new ParseInstallation();
395+
when(controller.getAsync())
396+
.thenReturn(Task.forResult(currentInstallation));
397+
ParseCorePlugins.getInstance()
398+
.registerCurrentInstallationController(controller);
399+
return controller;
400+
}
363401
}

0 commit comments

Comments
 (0)