Skip to content

Commit 8263fd7

Browse files
committed
Report missing localId as soft errors
1 parent bee5f89 commit 8263fd7

File tree

4 files changed

+45
-16
lines changed

4 files changed

+45
-16
lines changed

Parse/Parse/Internal/Commands/PFRESTCommand.m

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -174,41 +174,50 @@ - (void)maybeChangeServerOperation {
174174
}
175175
}
176176

177-
+ (BOOL)forEachLocalIdIn:(id)object doBlock:(BOOL(^)(PFObject *pointer))block {
177+
+ (BOOL)forEachLocalIdIn:(id)object doBlock:(BOOL(^)(PFObject *pointer, NSError **error))block error:(NSError **)error {
178178
__block BOOL modified = NO;
179179

180180
// If this is a Pointer with a local id, try to resolve it.
181181
if ([object isKindOfClass:[PFObject class]] && !((PFObject *)object).objectId) {
182-
return block(object);
182+
return block(object, error);
183183
}
184184

185185
if ([object isKindOfClass:[NSDictionary class]]) {
186+
__block NSError *localError;
187+
__block BOOL hasFailed = NO;
186188
[object enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL *stop) {
187-
if ([[self class] forEachLocalIdIn:obj doBlock:block]) {
189+
if ([[self class] forEachLocalIdIn:obj doBlock:block error:&localError]) {
188190
modified = YES;
189191
}
192+
if (localError) {
193+
*stop = YES;
194+
hasFailed = YES;
195+
}
190196
}];
197+
if (hasFailed && error) {
198+
*error = localError;
199+
}
191200
} else if ([object isKindOfClass:[NSArray class]]) {
192201
for (id value in object) {
193-
if ([[self class] forEachLocalIdIn:value doBlock:block]) {
202+
if ([[self class] forEachLocalIdIn:value doBlock:block error:error]) {
194203
modified = YES;
195204
}
196205
}
197206
} else if ([object isKindOfClass:[PFAddOperation class]]) {
198207
for (id value in ((PFAddOperation *)object).objects) {
199-
if ([[self class] forEachLocalIdIn:value doBlock:block]) {
208+
if ([[self class] forEachLocalIdIn:value doBlock:block error:error]) {
200209
modified = YES;
201210
}
202211
}
203212
} else if ([object isKindOfClass:[PFAddUniqueOperation class]]) {
204213
for (id value in ((PFAddUniqueOperation *)object).objects) {
205-
if ([[self class] forEachLocalIdIn:value doBlock:block]) {
214+
if ([[self class] forEachLocalIdIn:value doBlock:block error:error]) {
206215
modified = YES;
207216
}
208217
}
209218
} else if ([object isKindOfClass:[PFRemoveOperation class]]) {
210219
for (id value in ((PFRemoveOperation *)object).objects) {
211-
if ([[self class] forEachLocalIdIn:value doBlock:block]) {
220+
if ([[self class] forEachLocalIdIn:value doBlock:block error:error]) {
212221
modified = YES;
213222
}
214223
}
@@ -217,13 +226,16 @@ + (BOOL)forEachLocalIdIn:(id)object doBlock:(BOOL(^)(PFObject *pointer))block {
217226
return modified;
218227
}
219228

220-
- (BOOL)forEachLocalId:(BOOL(^)(PFObject *pointer))block error:(NSError **)error {
229+
- (BOOL)forEachLocalId:(BOOL(^)(PFObject *pointer, NSError **error))block error:(NSError **)error {
221230
NSDictionary *data = [[PFDecoder objectDecoder] decodeObject:self.parameters];
222231
if (!data) {
223232
return YES;
224233
}
225234

226-
if ([[self class] forEachLocalIdIn:data doBlock:block]) {
235+
if ([[self class] forEachLocalIdIn:data doBlock:block error:error]) {
236+
if (error && *error) {
237+
return NO;
238+
}
227239
self.parameters = [[PFPointerOrLocalIdObjectEncoder objectEncoder] encodeObject:data error:error];
228240
if (!self.parameters && error && *error) {
229241
return NO;
@@ -235,16 +247,19 @@ - (BOOL)forEachLocalId:(BOOL(^)(PFObject *pointer))block error:(NSError **)error
235247
- (BOOL)resolveLocalIds:(NSError * __autoreleasing *)error {
236248
__block NSError *firstError;
237249
__block BOOL pointerResolutionFailed = NO;
238-
BOOL paramEncodingFailed = [self forEachLocalId:^(PFObject *pointer) {
250+
BOOL paramEncodingSucceeded = [self forEachLocalId:^(PFObject *pointer, NSError **error) {
239251
NSError *localError;
240252
BOOL success = [pointer resolveLocalId:&localError];
241-
if (!success && !firstError) {
242-
firstError = localError;
253+
if (!success && localError) {
254+
*error = localError;
243255
pointerResolutionFailed = YES;
256+
if (!firstError) {
257+
firstError = localError;
258+
}
244259
}
245260
return YES;
246261
} error: error];
247-
if (paramEncodingFailed && *error) {
262+
if (!paramEncodingSucceeded && *error) {
248263
return NO;
249264
}
250265
if (pointerResolutionFailed && firstError) {

Parse/Parse/PFEncoder.m

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,12 @@ - (id)encodeObject:(id)object error:(NSError * __autoreleasing *) error {
9898
__block BOOL hasErrored = NO;
9999
__block NSError *encodingError = nil;
100100
[object enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
101-
dict[key] = [self encodeObject:obj error:&encodingError];
102-
if (!dict[key] && encodingError) {
101+
id result = [self encodeObject:obj error:&encodingError];
102+
if (!result && encodingError) {
103103
hasErrored = YES;
104104
*stop = YES;
105+
} else {
106+
dict[key] = result;
105107
}
106108
}];
107109
if (hasErrored) {

Parse/Parse/PFObject.m

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -783,7 +783,9 @@ - (NSString *)getOrCreateLocalId {
783783

784784
- (BOOL)resolveLocalId:(NSError *__autoreleasing*)error {
785785
@synchronized (lock) {
786-
PFConsistencyAssert(self.localId, @"Tried to resolve a localId for an object with no localId.");
786+
if (!self.localId) {
787+
PFConsistencyError(error, self.localId, NO , @"Tried to resolve a localId for an object with no localId.");
788+
}
787789
NSString *newObjectId = [[Parse _currentManager].coreManager.objectLocalIdStore objectIdForLocalId:self.localId];
788790

789791
// If we are resolving local ids, then this object is about to go over the network.

Parse/Tests/Unit/URLSessionCommandRunnerTests.m

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,4 +269,14 @@ - (void)testLocalIdResolutionFailure {
269269
XCTAssertEqualObjects(error.localizedDescription, @"Tried to save an object with a pointer to a new, unsaved object.");
270270
}
271271

272+
- (void)testLocalIdResolutionFailureWithNoLocalId {
273+
PFObject *object = [PFObject objectWithClassName:@"Yolo"];
274+
id command = [PFRESTCommand commandWithHTTPPath:@"" httpMethod:@"" parameters:@{@"object": object} sessionToken:nil error:nil];
275+
NSError *error;
276+
[command resolveLocalIds:&error];
277+
XCTAssertNotNil(error);
278+
XCTAssertEqualObjects(error.domain, PFParseErrorDomain);
279+
XCTAssertEqualObjects(error.localizedDescription, @"Tried to resolve a localId for an object with no localId.");
280+
}
281+
272282
@end

0 commit comments

Comments
 (0)