Skip to content

Commit 97011ac

Browse files
vdkdamiancbaker6
andauthored
feat: Added error comparing (#250)
* Added error comparing Add the ability to easily compare Swift Errors with ParseErrors. * Added tests * Fix SwiftLint script for autocorrection * Changelog * Recommendations from cbaker6 * Recommendations from cbaker6 * Description change * lint * Requested changes * Requested changes * nits on comments and structure Co-authored-by: Corey <[email protected]>
1 parent 51dfbe1 commit 97011ac

File tree

5 files changed

+174
-5
lines changed

5 files changed

+174
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.10.1...main)
55
* _Contributing to this repo? Add info about your change here to be included in the next release_
66

7+
__Improvements__
8+
- Added an extension to compare a Swift Error with a single ParseError or multiple ParseErrors ([#250](https://github.com/parse-community/Parse-Swift/pull/250)), thanks to [Damian Van de Kauter](https://github.com/novemTeam).
9+
710
### 1.10.1
811
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.10.0...1.10.1)
912

ParseSwift.playground/Pages/2 - Finding Objects.xcplaygroundpage/Contents.swift

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@ query.limit(2).find(callbackQueue: .main) { results in
5454
}
5555

5656
case .failure(let error):
57-
assertionFailure("Error querying: \(error)")
57+
if error.equalsTo(.objectNotFound) {
58+
assertionFailure("Object not found for this query")
59+
} else {
60+
assertionFailure("Error querying: \(error)")
61+
}
5862
}
5963
}
6064

@@ -80,7 +84,11 @@ query.first { results in
8084
print("Found score: \(score)")
8185

8286
case .failure(let error):
83-
assertionFailure("Error querying: \(error)")
87+
if error.containedIn([.objectNotFound, .invalidQuery]) {
88+
assertionFailure("The query is invalid or the object is not found.")
89+
} else {
90+
assertionFailure("Error querying: \(error)")
91+
}
8492
}
8593
}
8694

@@ -109,7 +117,11 @@ querySelect.first { results in
109117
print("Found score using select: \(score)")
110118

111119
case .failure(let error):
112-
assertionFailure("Error querying: \(error)")
120+
if let parseError = error.equalsTo(.objectNotFound) {
121+
assertionFailure("Object not found: \(parseError)")
122+
} else {
123+
assertionFailure("Error querying: \(error)")
124+
}
113125
}
114126
}
115127

@@ -124,7 +136,11 @@ queryExclude.first { results in
124136
print("Found score using exclude: \(score)")
125137

126138
case .failure(let error):
127-
assertionFailure("Error querying: \(error)")
139+
if let parseError = error.containedIn(.objectNotFound, .invalidQuery) {
140+
assertionFailure("Matching error found: \(parseError)")
141+
} else {
142+
assertionFailure("Error querying: \(error)")
143+
}
128144
}
129145
}
130146

ParseSwift.xcodeproj/project.pbxproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1723,7 +1723,7 @@
17231723
);
17241724
runOnlyForDeploymentPostprocessing = 0;
17251725
shellPath = /bin/sh;
1726-
shellScript = "if which swiftlint >/dev/null; then\n swiftlint autocorrect && swiftlint --strict\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
1726+
shellScript = "if which swiftlint >/dev/null; then\n swiftlint --fix --strict\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi\n";
17271727
};
17281728
918CED61268A23A700CFDC83 /* SwiftLint */ = {
17291729
isa = PBXShellScriptBuildPhase;

Sources/ParseSwift/Types/ParseError.swift

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,3 +406,123 @@ extension ParseError: CustomStringConvertible {
406406
debugDescription
407407
}
408408
}
409+
410+
// MARK: Compare Errors
411+
public extension Error {
412+
413+
/**
414+
Returns the respective `ParseError` if the given `ParseError` code is equal to the error.
415+
416+
**Example use case:**
417+
~~~
418+
if let parseError = error.equalsTo(.objectNotFound) {
419+
print(parseError.description)
420+
}
421+
~~~
422+
- parameter errorCode: A `ParseError` code to compare to.
423+
424+
- returns: Returns the `ParseError` with respect to the `Error`. If the error is not a `ParseError`, returns nil.
425+
*/
426+
func equalsTo(_ errorCode: ParseError.Code) -> ParseError? {
427+
guard let error = self as? ParseError,
428+
error.code == errorCode else {
429+
return nil
430+
}
431+
return error
432+
}
433+
434+
/**
435+
Validates if the given `ParseError` code is equal to the error.
436+
437+
**Example use case:**
438+
~~~
439+
if error.equalsTo(.objectNotFound) {
440+
//Do stuff
441+
}
442+
~~~
443+
- parameter errorCode: A `ParseError` code to compare to.
444+
445+
- returns: A boolean indicating whether or not the `Error` is the `errorCode`.
446+
*/
447+
func equalsTo(_ errorCode: ParseError.Code) -> Bool {
448+
guard equalsTo(errorCode) != nil else {
449+
return false
450+
}
451+
return true
452+
}
453+
454+
/**
455+
Returns the respective `ParseError` if the `Error` is contained in the array of `ParseError` codes.
456+
457+
**Example use case:**
458+
~~~
459+
if let parseError = error.containedIn([.objectNotFound, .invalidQuery]) {
460+
print(parseError.description)
461+
}
462+
~~~
463+
- parameter errorCodes: An array of zero or more of `ParseError` codes to compare to.
464+
465+
- returns: Returns the `ParseError` with respect to the `Error`. If the error is not a `ParseError`, returns nil.
466+
*/
467+
func containedIn(_ errorCodes: [ParseError.Code]) -> ParseError? {
468+
guard let error = self as? ParseError,
469+
errorCodes.contains(error.code) == true else {
470+
return nil
471+
}
472+
return error
473+
}
474+
475+
/**
476+
Returns the respective `ParseError` if the `Error` is contained in the list of `ParseError` codes.
477+
478+
**Example use case:**
479+
~~~
480+
if let parseError = error.containedIn(.objectNotFound, .invalidQuery) {
481+
print(parseError.description)
482+
}
483+
~~~
484+
- parameter errorCodes: A variadic amount of zero or more of `ParseError` codes to compare to.
485+
486+
- returns: Returns the `ParseError` with respect to the `Error`. If the error is not a `ParseError`, returns nil.
487+
*/
488+
func containedIn(_ errorCodes: ParseError.Code...) -> ParseError? {
489+
containedIn(errorCodes)
490+
}
491+
492+
/**
493+
Validates if the given `ParseError` codes contains the error.
494+
495+
**Example use case:**
496+
~~~
497+
if error.containedIn([.objectNotFound, .invalidQuery]) {
498+
//Do stuff
499+
}
500+
~~~
501+
- parameter errorCodes: An array of zero or more of `ParseError` codes to compare to.
502+
503+
- returns: A boolean indicating whether or not the `Error` is contained in the `errorCodes`.
504+
*/
505+
func containedIn(_ errorCodes: [ParseError.Code]) -> Bool {
506+
guard containedIn(errorCodes) != nil else {
507+
return false
508+
}
509+
return true
510+
}
511+
512+
/**
513+
Validates if the given `ParseError` codes contains the error.
514+
515+
**Example use case:**
516+
~~~
517+
if error.containedIn(.objectNotFound, .invalidQuery) {
518+
//Do stuff
519+
}
520+
~~~
521+
- parameter errorCodes: A variadic amount of zero or more of `ParseError` codes to compare to.
522+
523+
- returns: A boolean indicating whether or not the `Error` is contained in the `errorCodes`.
524+
*/
525+
func containedIn(_ errorCodes: ParseError.Code...) -> Bool {
526+
containedIn(errorCodes)
527+
}
528+
}

Tests/ParseSwiftTests/ParseErrorTests.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,34 @@ class ParseErrorTests: XCTestCase {
6262
"ParseError code=\(ParseError.Code.other.rawValue) error=\(message) otherCode=\(code)")
6363
XCTAssertEqual(decoded.otherCode, code)
6464
}
65+
66+
func testCompare() throws {
67+
let code = ParseError.Code.objectNotFound.rawValue
68+
let message = "testing ParseError"
69+
guard let encoded = "{\"error\":\"\(message)\",\"code\":\(code)}".data(using: .utf8) else {
70+
XCTFail("Should have unwrapped")
71+
return
72+
}
73+
let decoded = try ParseCoding.jsonDecoder().decode(ParseError.self, from: encoded)
74+
75+
let error: Error = decoded
76+
77+
XCTAssertTrue(error.equalsTo(.objectNotFound))
78+
XCTAssertFalse(error.equalsTo(.invalidQuery))
79+
80+
XCTAssertTrue(error.containedIn(.objectNotFound, .invalidQuery))
81+
XCTAssertFalse(error.containedIn(.operationForbidden, .invalidQuery))
82+
83+
XCTAssertTrue(error.containedIn([.objectNotFound, .invalidQuery]))
84+
XCTAssertFalse(error.containedIn([.operationForbidden, .invalidQuery]))
85+
86+
XCTAssertNotNil(error.equalsTo(.objectNotFound))
87+
XCTAssertNil(error.equalsTo(.invalidQuery))
88+
89+
XCTAssertNotNil(error.containedIn(.objectNotFound, .invalidQuery))
90+
XCTAssertNil(error.containedIn(.operationForbidden, .invalidQuery))
91+
92+
XCTAssertNotNil(error.containedIn([.objectNotFound, .invalidQuery]))
93+
XCTAssertNil(error.containedIn([.operationForbidden, .invalidQuery]))
94+
}
6595
}

0 commit comments

Comments
 (0)