Skip to content

Commit 3637bf0

Browse files
committed
Unify and provide consistent client-side error and exception reporting.
1 parent dd531aa commit 3637bf0

File tree

14 files changed

+121
-154
lines changed

14 files changed

+121
-154
lines changed

Parse/Internal/FieldOperation/PFFieldOperation.m

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,17 @@
2525
@implementation PFFieldOperation
2626

2727
- (id)encodeWithObjectEncoder:(PFEncoder *)objectEncoder {
28-
PFConsistencyAssert(NO, @"Operation is invalid.");
28+
PFConsistencyAssertionFailure(@"Operation is invalid.");
2929
return nil;
3030
}
3131

3232
- (PFFieldOperation *)mergeWithPrevious:(PFFieldOperation *)previous {
33-
PFConsistencyAssert(NO, @"Operation is invalid.");
33+
PFConsistencyAssertionFailure(@"Operation is invalid.");
3434
return nil;
3535
}
3636

3737
- (id)applyToValue:(id)oldValue forKey:(NSString *)key {
38-
PFConsistencyAssert(NO, @"Operation is invalid.");
38+
PFConsistencyAssertionFailure(@"Operation is invalid.");
3939
return nil;
4040
}
4141

@@ -153,7 +153,7 @@ - (PFFieldOperation *)mergeWithPrevious:(PFFieldOperation *)previous {
153153
withNumber:((PFIncrementOperation *)previous).amount];
154154
return [PFIncrementOperation incrementWithAmount:newAmount];
155155
}
156-
[NSException raise:NSInternalInconsistencyException format:@"Operation is invalid after previous operation."];
156+
PFConsistencyAssertionFailure(@"This operation is invalid after previous operation.");
157157
return nil;
158158
}
159159

@@ -208,15 +208,15 @@ - (PFFieldOperation *)mergeWithPrevious:(PFFieldOperation *)previous {
208208
NSArray *newArray = [oldArray arrayByAddingObjectsFromArray:self.objects];
209209
return [PFSetOperation setWithValue:newArray];
210210
} else {
211-
[NSException raise:NSInternalInconsistencyException format:@"You can't add an item to a non-array."];
211+
PFConsistencyAssertionFailure(@"Unable to add an item to a non-array.");
212212
return nil;
213213
}
214214
} else if ([previous isKindOfClass:[PFAddOperation class]]) {
215215
NSMutableArray *newObjects = [((PFAddOperation *)previous).objects mutableCopy];
216216
[newObjects addObjectsFromArray:self.objects];
217217
return [[self class] addWithObjects:newObjects];
218218
}
219-
[NSException raise:NSInternalInconsistencyException format:@"Operation is invalid after previous operation."];
219+
PFConsistencyAssertionFailure(@"This operation is invalid after previous operation.");
220220
return nil;
221221
}
222222

@@ -226,7 +226,7 @@ - (id)applyToValue:(id)oldValue forKey:(NSString *)key {
226226
} else if ([oldValue isKindOfClass:[NSArray class]]) {
227227
return [((NSArray *)oldValue)arrayByAddingObjectsFromArray:self.objects];
228228
}
229-
[NSException raise:NSInternalInconsistencyException format:@"Operation is invalid after previous operation."];
229+
PFConsistencyAssertionFailure(@"This operation is invalid after previous operation.");
230230
return nil;
231231
}
232232

@@ -267,14 +267,14 @@ - (PFFieldOperation *)mergeWithPrevious:(PFFieldOperation *)previous {
267267
NSArray *oldArray = (((PFSetOperation *)previous).value);
268268
return [PFSetOperation setWithValue:[self applyToValue:oldArray forKey:nil]];
269269
} else {
270-
[NSException raise:NSInternalInconsistencyException format:@"You can't add an item to a non-array."];
270+
PFConsistencyAssertionFailure(@"Unable to add an item to a non-array.");
271271
return nil;
272272
}
273273
} else if ([previous isKindOfClass:[PFAddUniqueOperation class]]) {
274274
NSArray *previousObjects = ((PFAddUniqueOperation *)previous).objects;
275275
return [[self class] addUniqueWithObjects:[self applyToValue:previousObjects forKey:nil]];
276276
}
277-
[NSException raise:NSInternalInconsistencyException format:@"Operation is invalid after previous operation."];
277+
PFConsistencyAssertionFailure(@"This operation is invalid after previous operation.");
278278
return nil;
279279
}
280280

@@ -302,7 +302,7 @@ - (id)applyToValue:(id)oldValue forKey:(NSString *)key {
302302
}
303303
return newValue;
304304
}
305-
[NSException raise:NSInternalInconsistencyException format:@"Operation is invalid after previous operation."];
305+
PFConsistencyAssertionFailure(@"This operation is invalid after previous operation.");
306306
return nil;
307307
}
308308

@@ -336,22 +336,22 @@ - (PFFieldOperation *)mergeWithPrevious:(PFFieldOperation *)previous {
336336
if (!previous) {
337337
return self;
338338
} else if ([previous isKindOfClass:[PFDeleteOperation class]]) {
339-
[NSException raise:NSInternalInconsistencyException format:@"You can't remove items from a deleted array."];
339+
PFConsistencyAssertionFailure(@"Unable to remove items from a deleted array.");
340340
return nil;
341341
} else if ([previous isKindOfClass:[PFSetOperation class]]) {
342342
if ([((PFSetOperation *)previous).value isKindOfClass:[NSArray class]]) {
343343
NSArray *oldArray = ((PFSetOperation *)previous).value;
344344
return [PFSetOperation setWithValue:[self applyToValue:oldArray forKey:nil]];
345345
} else {
346-
[NSException raise:NSInternalInconsistencyException format:@"You can't add an item to a non-array."];
346+
PFConsistencyAssertionFailure(@"Unable to add an item to a non-array.");
347347
return nil;
348348
}
349349
} else if ([previous isKindOfClass:[PFRemoveOperation class]]) {
350350
NSArray *newObjects = [((PFRemoveOperation *)previous).objects arrayByAddingObjectsFromArray:self.objects];
351351
return [PFRemoveOperation removeWithObjects:newObjects];
352352
}
353353

354-
[NSException raise:NSInternalInconsistencyException format:@"Operation is invalid after previous operation."];
354+
PFConsistencyAssertionFailure(@"This operation is invalid after previous operation.");
355355
return nil;
356356
}
357357

@@ -379,7 +379,7 @@ - (id)applyToValue:(id)oldValue forKey:(NSString *)key {
379379
}
380380
return newValue;
381381
}
382-
[NSException raise:NSInternalInconsistencyException format:@"Operation is invalid after previous operation."];
382+
PFConsistencyAssertionFailure(@"This operation is invalid after previous operation.");
383383
return nil;
384384
}
385385

@@ -474,8 +474,7 @@ - (id)encodeWithObjectEncoder:(PFEncoder *)objectEncoder {
474474
if (removeDict) {
475475
return removeDict;
476476
}
477-
478-
[NSException raise:NSInternalInconsistencyException format:@"A PFRelationOperation was created without any data."];
477+
PFConsistencyAssertionFailure(@"A PFRelationOperation was created without any data.");
479478
return nil;
480479
}
481480

@@ -535,7 +534,7 @@ - (id)applyToValue:(id)oldValue forKey:(NSString *)key {
535534
}
536535
}
537536
} else {
538-
[NSException raise:NSInternalInconsistencyException format:@"Operation is invalid after previous operation."];
537+
PFConsistencyAssertionFailure(@"This operation is invalid after previous operation.");
539538
return nil;
540539
}
541540

Parse/Internal/Installation/Controller/PFInstallationController.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,12 +83,12 @@ - (BFTask *)processFetchResultAsync:(NSDictionary *)result forObject:(PFObject *
8383
///--------------------------------------
8484

8585
- (BFTask *)deleteObjectAsync:(PFObject *)object withSessionToken:(nullable NSString *)sessionToken {
86-
PFConsistencyAssert(NO, @"Installations cannot be deleted.");
86+
PFConsistencyAssertionFailure(@"Installations cannot be deleted.");
8787
return nil;
8888
}
8989

9090
- (BFTask *)processDeleteResultAsync:(nullable NSDictionary *)result forObject:(PFObject *)object {
91-
PFConsistencyAssert(NO, @"Installations cannot be deleted.");
91+
PFConsistencyAssertionFailure(@"Installations cannot be deleted.");
9292
return nil;
9393
}
9494

Parse/Internal/LocalDataStore/OfflineQueryLogic/PFOfflineQueryLogic.m

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ - (id)valueForContainer:(id)container
126126
return [self valueForContainer:restFormat key:rest depth:depth + 1];
127127
}
128128
}
129-
[NSException raise:NSInvalidArgumentException format:@"Key %@ is invalid", key];
129+
PFParameterAssertionFailure(@"Key %@ is invalid.", key);
130130
}
131131
return [self valueForContainer:value key:rest depth:depth + 1];
132132
}
@@ -152,7 +152,7 @@ - (id)valueForContainer:(id)container
152152
} else if (container == nil) {
153153
return nil;
154154
} else {
155-
[NSException raise:NSInvalidArgumentException format:@"Bad key %@", key];
155+
PFParameterAssertionFailure(@"Bad key %@", key);
156156
// Shouldn't reach here.
157157
return nil;
158158
}
@@ -457,9 +457,7 @@ + (BOOL)matchesValue:(id)value
457457
} else if ([operator isEqualToString:PFQueryKeyWithin]) {
458458
return [self matchesValue:value within:constraint];
459459
}
460-
461-
[NSException raise:NSInvalidArgumentException
462-
format:@"The offline store does not yet support %@ operator.", operator];
460+
PFParameterAssertionFailure(@"Local Datastore does not yet support %@ operator.", operator);
463461
// Shouldn't reach here
464462
return YES;
465463
}
@@ -710,10 +708,9 @@ - (BFTask *)fetchIncludeAsync:(NSString *)include
710708
// throwing an exception.
711709
return nil;
712710
}
713-
NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException
714-
reason:@"include is invalid"
715-
userInfo:nil];
716-
return [BFTask taskWithException:exception];
711+
NSError *error = [PFErrorUtilities errorWithCode:kPFErrorInvalidNestedKey
712+
message:@"include is invalid"];
713+
return [BFTask taskWithError:error];
717714
}] continueWithSuccessBlock:^id(BFTask *task) {
718715
return [self fetchIncludeAsync:rest container:task.result database:database];
719716
}];

Parse/Internal/LocalDataStore/OfflineStore/PFOfflineStore.m

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -178,8 +178,7 @@ - (instancetype)initWithFileManager:(PFFileManager *)fileManager options:(PFOffl
178178
PFOfflineStoreKeyOfJSON, PFOfflineStoreTableOfObjects, PFOfflineStoreKeyOfUUID];
179179
return [database executeQueryAsync:query withArgumentsInArray:@[ uuid ] block:^id(PFSQLiteDatabaseResult *_Nonnull result) {
180180
if (![result next]) {
181-
[NSException raise:NSInternalInconsistencyException
182-
format:@"Attempted to find non-existent uuid %@.", uuid];
181+
PFConsistencyAssertionFailure(@"Attempted to find non-existent uuid %@. Please report this issue with stack traces and logs.", uuid);
183182
}
184183
return [result stringForColumnIndex:0];
185184
}];
@@ -189,10 +188,10 @@ - (instancetype)initWithFileManager:(PFFileManager *)fileManager options:(PFOffl
189188
if (uuidTask && !(self.options & PFOfflineStoreOptionAlwaysFetchFromSQLite)) {
190189
// This object is an existing ParseObject, and we must've already pulled its data
191190
// out of the offline store, or else we wouldn't know its UUID. This should never happen.
192-
NSString *message = @"Object must have already been fetched but isn't marked as fetched.";
193-
[tcs setException:[NSException exceptionWithName:NSInternalInconsistencyException
194-
reason:message
195-
userInfo:nil]];
191+
NSError *error = [PFErrorUtilities errorWithCode:kPFErrorObjectNotFound
192+
message:@"Object must have already been fetched but isn't marked as fetched."
193+
shouldLog:NO];
194+
[tcs setError:error];
196195

197196
@synchronized(self.lock) {
198197
[self.fetchedObjects removeObjectForKey:object];
@@ -215,9 +214,8 @@ - (instancetype)initWithFileManager:(PFFileManager *)fileManager options:(PFOffl
215214
__block NSString *newUUID = nil;
216215
jsonStringTask = [[database executeQueryAsync:query withArgumentsInArray:@[ className, objectId ] block:^id(PFSQLiteDatabaseResult *_Nonnull result) {
217216
if (![result next]) {
218-
NSString *errorMessage = @"This object is not available in the offline cache.";
219217
NSError *error = [PFErrorUtilities errorWithCode:kPFErrorCacheMiss
220-
message:errorMessage
218+
message:@"This object is not available in the offline cache."
221219
shouldLog:NO];
222220
return [BFTask taskWithError:error];
223221
}
@@ -581,10 +579,10 @@ - (BFTask *)findAsyncForQueryState:(PFQueryState *)queryState
581579
@synchronized(self.lock) {
582580
fetchTask = [self.fetchedObjects objectForKey:object];
583581
if (!fetchTask) {
584-
NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException
585-
reason:@"An object cannot be updated if it wasn't fetched"
586-
userInfo:nil];
587-
return [BFTask taskWithException:exception];
582+
NSError *error = [PFErrorUtilities errorWithCode:kPFErrorObjectNotFound
583+
message:@"An object cannot be updated if it wasn't fetched"
584+
shouldLog:NO];
585+
return [BFTask taskWithError:error];
588586
}
589587
}
590588
return [fetchTask continueWithBlock:^id(BFTask *task) {
@@ -909,8 +907,7 @@ - (BFTask *)findAsyncForQueryState:(PFQueryState *)queryState
909907
__block NSString *objectId = nil;
910908
return [[database executeQueryAsync:query withArgumentsInArray:@[ uuid ] block:^id(PFSQLiteDatabaseResult *result) {
911909
if (![result next]) {
912-
[NSException raise:NSInternalInconsistencyException
913-
format:@"Attempted to find non-existent uuid %@", uuid]; // TODO: (nlutsenko) Convert to errors.
910+
PFConsistencyAssertionFailure(@"Attempted to find non-existent uuid %@. Please report this issue with stack traces and logs.", uuid);
914911
}
915912

916913
className = [result stringForColumnIndex:0];

Parse/Internal/PFAssert.h

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,40 +24,57 @@
2424
} \
2525
} while(0)
2626

27+
/**
28+
Raises an `NSInvalidArgumentException`. Use `description` to supply the way to fix the exception.
29+
*/
30+
#define PFParameterAssertionFailure(description, ...) \
31+
do {\
32+
[NSException raise:NSInvalidArgumentException \
33+
format:description, ##__VA_ARGS__]; \
34+
} while(0)
35+
2736
/**
2837
Raises an `NSRangeException` if the `condition` does not pass.
2938
Use `description` to supply the way to fix the exception.
3039
*/
3140
#define PFRangeAssert(condition, description, ...) \
32-
do {\
33-
if (!(condition)) { \
34-
[NSException raise:NSRangeException \
35-
format:description, ##__VA_ARGS__]; \
36-
} \
41+
do {\
42+
if (!(condition)) { \
43+
[NSException raise:NSRangeException \
44+
format:description, ##__VA_ARGS__]; \
45+
} \
3746
} while(0)
3847

3948
/**
4049
Raises an `NSInternalInconsistencyException` if the `condition` does not pass.
4150
Use `description` to supply the way to fix the exception.
4251
*/
4352
#define PFConsistencyAssert(condition, description, ...) \
44-
do { \
45-
if (!(condition)) { \
46-
[NSException raise:NSInternalInconsistencyException \
47-
format:description, ##__VA_ARGS__]; \
48-
} \
49-
} while(0)
53+
do { \
54+
if (!(condition)) { \
55+
[NSException raise:NSInternalInconsistencyException \
56+
format:description, ##__VA_ARGS__]; \
57+
} \
58+
} while(0)
59+
60+
/**
61+
Raises an `NSInternalInconsistencyException`. Use `description` to supply the way to fix the exception.
62+
*/
63+
#define PFConsistencyAssertionFailure(description, ...) \
64+
do {\
65+
[NSException raise:NSInternalInconsistencyException \
66+
format:description, ##__VA_ARGS__]; \
67+
} while(0)
5068

5169
/**
5270
Always raises `NSInternalInconsistencyException` with details
5371
about the method used and class that received the message
5472
*/
5573
#define PFNotDesignatedInitializer() \
5674
do { \
57-
PFConsistencyAssert(NO, \
58-
@"%@ is not the designated initializer for instances of %@.", \
59-
NSStringFromSelector(_cmd), \
60-
NSStringFromClass([self class])); \
75+
PFConsistencyAssertionFailure(@"%@ is not the designated initializer for instances of %@.", \
76+
NSStringFromSelector(_cmd), \
77+
NSStringFromClass([self class])); \
6178
return nil; \
6279
} while (0)
6380

Parse/Internal/PFEncoder.m

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,9 +55,6 @@ - (id)encodeObject:(id)object {
5555
// Returning this empty object is strictly wrong, but we have to have *something*
5656
// to put into an object's mutable container cache, and this is just about the
5757
// best we can do right now.
58-
//
59-
// [NSException raise:NSInternalInconsistencyException
60-
// format:@"Tried to serialize an unsaved file."];
6158
return @{ @"__type" : @"File" };
6259
}
6360
return @{
@@ -122,7 +119,7 @@ + (instancetype)objectEncoder {
122119
}
123120

124121
- (id)encodeParseObject:(PFObject *)object {
125-
[NSException raise:NSInternalInconsistencyException format:@"PFObjects are not allowed here."];
122+
PFConsistencyAssertionFailure(@"PFObjects are not allowed here.");
126123
return nil;
127124
}
128125

Parse/Internal/PFEventuallyQueue.m

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -325,11 +325,10 @@ - (BFTask *)_runCommand:(id<PFNetworkCommand>)command withIdentifier:(NSString *
325325
return [self.dataSource.commandRunner runCommandAsync:(PFRESTCommand *)command withOptions:0];
326326
}
327327

328-
NSString *reason = [NSString stringWithFormat:@"Can't find a compatible runner for command %@.", command];
329-
NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException
330-
reason:reason
331-
userInfo:nil];
332-
return [BFTask taskWithException:exception];
328+
NSError *error = [PFErrorUtilities errorWithCode:kPFErrorInternalServer
329+
message:[NSString stringWithFormat:@"Can't find a compatible runner for command %@.", command]
330+
shouldLog:NO];
331+
return [BFTask taskWithError:error];
333332
}
334333

335334
- (BFTask *)_didFinishRunningCommand:(id<PFNetworkCommand>)command

Parse/Internal/PFInternalUtils.m

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,7 @@ + (void)appendObject:(id)object toString:(NSMutableString *)string {
152152
} else if ([object isKindOfClass:[NSNull class]]) {
153153
[self appendNullToString:string];
154154
} else {
155-
[NSException raise:NSInvalidArgumentException
156-
format:@"Couldn't create cache key from %@", object];
155+
PFParameterAssertionFailure(@"Couldn't create cache key from %@", object);
157156
}
158157
}
159158

Parse/Internal/PFPinningEventuallyQueue.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -281,10 +281,10 @@ - (BFTask *)_waitForOperationSet:(PFOperationSet *)operationSet eventuallyPin:(P
281281
}
282282
});
283283
if (uuid == nil) {
284-
NSException *exception = [NSException exceptionWithName:NSInternalInconsistencyException
285-
reason:@"Either operationSet or eventuallyPin must be set"
286-
userInfo:nil];
287-
return [BFTask taskWithException:exception];
284+
NSError *error = [PFErrorUtilities errorWithCode:kPFErrorIncorrectType
285+
message:@"Either operationSet or eventuallyPin must be set"
286+
shouldLog:NO];
287+
return [BFTask taskWithError:error];
288288
}
289289
return [BFTask taskWithResult:nil];
290290
}

0 commit comments

Comments
 (0)