Skip to content

feat: Added error comparing #250

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Oct 3, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.10.1...main)
* _Contributing to this repo? Add info about your change here to be included in the next release_

__Improvements__
- 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).

### 1.10.1
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.10.0...1.10.1)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ query.limit(2).find(callbackQueue: .main) { results in
}

case .failure(let error):
assertionFailure("Error querying: \(error)")
if error.equalsTo(.objectNotFound) {
assertionFailure("Object not found for this query")
} else {
assertionFailure("Error querying: \(error)")
}
}
}

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

case .failure(let error):
assertionFailure("Error querying: \(error)")
if error.containedIn([.objectNotFound, .invalidQuery]) {
assertionFailure("The query is invalid or the object is not found.")
} else {
assertionFailure("Error querying: \(error)")
}
}
}

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

case .failure(let error):
assertionFailure("Error querying: \(error)")
if let parseError = error.equalsTo(.objectNotFound) {
assertionFailure("Object not found: \(parseError)")
} else {
assertionFailure("Error querying: \(error)")
}
}
}

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

case .failure(let error):
assertionFailure("Error querying: \(error)")
if let parseError = error.containedIn(.objectNotFound, .invalidQuery) {
assertionFailure("Matching error found: \(parseError)")
} else {
assertionFailure("Error querying: \(error)")
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion ParseSwift.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1723,7 +1723,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
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";
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";
};
918CED61268A23A700CFDC83 /* SwiftLint */ = {
isa = PBXShellScriptBuildPhase;
Expand Down
120 changes: 120 additions & 0 deletions Sources/ParseSwift/Types/ParseError.swift
Original file line number Diff line number Diff line change
Expand Up @@ -406,3 +406,123 @@ extension ParseError: CustomStringConvertible {
debugDescription
}
}

// MARK: Compare Errors
public extension Error {

/**
Returns the respective `ParseError` if the given `ParseError` code is equal to the error.

**Example use case:**
~~~
if let parseError = error.equalsTo(.objectNotFound) {
print(parseError.description)
}
~~~
- parameter errorCode: A `ParseError` code to compare to.

- returns: Returns the `ParseError` with respect to the `Error`. If the error is not a `ParseError`, returns nil.
*/
func equalsTo(_ errorCode: ParseError.Code) -> ParseError? {
guard let error = self as? ParseError,
error.code == errorCode else {
return nil
}
return error
}

/**
Validates if the given `ParseError` code is equal to the error.

**Example use case:**
~~~
if error.equalsTo(.objectNotFound) {
//Do stuff
}
~~~
- parameter errorCode: A `ParseError` code to compare to.

- returns: A boolean indicating whether or not the `Error` is the `errorCode`.
*/
func equalsTo(_ errorCode: ParseError.Code) -> Bool {
guard equalsTo(errorCode) != nil else {
return false
}
return true
}

/**
Returns the respective `ParseError` if the `Error` is contained in the array of `ParseError` codes.

**Example use case:**
~~~
if let parseError = error.containedIn([.objectNotFound, .invalidQuery]) {
print(parseError.description)
}
~~~
- parameter errorCodes: An array of zero or more of `ParseError` codes to compare to.

- returns: Returns the `ParseError` with respect to the `Error`. If the error is not a `ParseError`, returns nil.
*/
func containedIn(_ errorCodes: [ParseError.Code]) -> ParseError? {
guard let error = self as? ParseError,
errorCodes.contains(error.code) == true else {
return nil
}
return error
}

/**
Returns the respective `ParseError` if the `Error` is contained in the list of `ParseError` codes.

**Example use case:**
~~~
if let parseError = error.containedIn(.objectNotFound, .invalidQuery) {
print(parseError.description)
}
~~~
- parameter errorCodes: A variadic amount of zero or more of `ParseError` codes to compare to.

- returns: Returns the `ParseError` with respect to the `Error`. If the error is not a `ParseError`, returns nil.
*/
func containedIn(_ errorCodes: ParseError.Code...) -> ParseError? {
containedIn(errorCodes)
}

/**
Validates if the given `ParseError` codes contains the error.

**Example use case:**
~~~
if error.containedIn([.objectNotFound, .invalidQuery]) {
//Do stuff
}
~~~
- parameter errorCodes: An array of zero or more of `ParseError` codes to compare to.

- returns: A boolean indicating whether or not the `Error` is contained in the `errorCodes`.
*/
func containedIn(_ errorCodes: [ParseError.Code]) -> Bool {
guard containedIn(errorCodes) != nil else {
return false
}
return true
}

/**
Validates if the given `ParseError` codes contains the error.

**Example use case:**
~~~
if error.containedIn(.objectNotFound, .invalidQuery) {
//Do stuff
}
~~~
- parameter errorCodes: A variadic amount of zero or more of `ParseError` codes to compare to.

- returns: A boolean indicating whether or not the `Error` is contained in the `errorCodes`.
*/
func containedIn(_ errorCodes: ParseError.Code...) -> Bool {
containedIn(errorCodes)
}
}
30 changes: 30 additions & 0 deletions Tests/ParseSwiftTests/ParseErrorTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,34 @@ class ParseErrorTests: XCTestCase {
"ParseError code=\(ParseError.Code.other.rawValue) error=\(message) otherCode=\(code)")
XCTAssertEqual(decoded.otherCode, code)
}

func testCompare() throws {
let code = ParseError.Code.objectNotFound.rawValue
let message = "testing ParseError"
guard let encoded = "{\"error\":\"\(message)\",\"code\":\(code)}".data(using: .utf8) else {
XCTFail("Should have unwrapped")
return
}
let decoded = try ParseCoding.jsonDecoder().decode(ParseError.self, from: encoded)

let error: Error = decoded

XCTAssertTrue(error.equalsTo(.objectNotFound))
XCTAssertFalse(error.equalsTo(.invalidQuery))

XCTAssertTrue(error.containedIn(.objectNotFound, .invalidQuery))
XCTAssertFalse(error.containedIn(.operationForbidden, .invalidQuery))

XCTAssertTrue(error.containedIn([.objectNotFound, .invalidQuery]))
XCTAssertFalse(error.containedIn([.operationForbidden, .invalidQuery]))

XCTAssertNotNil(error.equalsTo(.objectNotFound))
XCTAssertNil(error.equalsTo(.invalidQuery))

XCTAssertNotNil(error.containedIn(.objectNotFound, .invalidQuery))
XCTAssertNil(error.containedIn(.operationForbidden, .invalidQuery))

XCTAssertNotNil(error.containedIn([.objectNotFound, .invalidQuery]))
XCTAssertNil(error.containedIn([.operationForbidden, .invalidQuery]))
}
}