Skip to content

Commit 457ef7c

Browse files
dblythycbaker6TomWFox
authored
new: allow for custom error codes from Parse Cloud (#165)
* new: allow for custom error codes from Parse Cloud * Update APICommandTests.swift * Update ParseError.swift * fix lint * Decode parse otherCode error and add tests * Update Sources/ParseSwift/Types/ParseError.swift Co-authored-by: Tom Fox <[email protected]> * add guard * Update Sources/ParseSwift/Types/ParseError.swift Co-authored-by: Corey <[email protected]> * Update Tests/ParseSwiftTests/ParseErrorTests.swift Co-authored-by: Corey <[email protected]> * Update CHANGELOG.md Co-authored-by: Corey <[email protected]> Co-authored-by: Tom Fox <[email protected]>
1 parent 603486a commit 457ef7c

File tree

6 files changed

+126
-4
lines changed

6 files changed

+126
-4
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
__Improvements__
88
- Ensure pipeline and fields are checked when comparing queries ([#163](https://github.com/parse-community/Parse-Swift/pull/163)), thanks to [Corey Baker](https://github.com/cbaker6).
9+
- Allow custom error codes to be thrown from Cloud Functions ([#165](https://github.com/parse-community/Parse-Swift/pull/165)), thanks to [Daniel Blyth](https://github.com/dblythy).
910

1011
### 1.8.1
1112
[Full Changelog](https://github.com/parse-community/Parse-Swift/compare/1.8.0...1.8.1)

ParseSwift.xcodeproj/project.pbxproj

+9-1
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,9 @@
385385
91678710259BC5D600BB5B4E /* ParseCloudTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 916786EF259BC59600BB5B4E /* ParseCloudTests.swift */; };
386386
9167871A259BC5D600BB5B4E /* ParseCloudTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 916786EF259BC59600BB5B4E /* ParseCloudTests.swift */; };
387387
9194657824F16E330070296B /* ParseACLTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9194657724F16E330070296B /* ParseACLTests.swift */; };
388+
91B40651267A66ED00B129CD /* ParseErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91B40650267A66ED00B129CD /* ParseErrorTests.swift */; };
389+
91B40652267A66ED00B129CD /* ParseErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91B40650267A66ED00B129CD /* ParseErrorTests.swift */; };
390+
91B40653267A66ED00B129CD /* ParseErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91B40650267A66ED00B129CD /* ParseErrorTests.swift */; };
388391
91CB9537265966DF0043E5D6 /* ParseAnanlyticsCombineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91CB9536265966DF0043E5D6 /* ParseAnanlyticsCombineTests.swift */; };
389392
91CB9538265966DF0043E5D6 /* ParseAnanlyticsCombineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91CB9536265966DF0043E5D6 /* ParseAnanlyticsCombineTests.swift */; };
390393
91CB9539265966DF0043E5D6 /* ParseAnanlyticsCombineTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91CB9536265966DF0043E5D6 /* ParseAnanlyticsCombineTests.swift */; };
@@ -705,6 +708,7 @@
705708
916786E1259B7DDA00BB5B4E /* ParseCloud.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseCloud.swift; sourceTree = "<group>"; };
706709
916786EF259BC59600BB5B4E /* ParseCloudTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseCloudTests.swift; sourceTree = "<group>"; };
707710
9194657724F16E330070296B /* ParseACLTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseACLTests.swift; sourceTree = "<group>"; };
711+
91B40650267A66ED00B129CD /* ParseErrorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseErrorTests.swift; sourceTree = "<group>"; };
708712
91CB9536265966DF0043E5D6 /* ParseAnanlyticsCombineTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseAnanlyticsCombineTests.swift; sourceTree = "<group>"; };
709713
F971F4F524DE381A006CB79B /* ParseEncoderExtraTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseEncoderExtraTests.swift; sourceTree = "<group>"; };
710714
F97B45B424D9C6F200F4A88B /* ParseCoding.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ParseCoding.swift; sourceTree = "<group>"; };
@@ -860,9 +864,9 @@
860864
70DFEA892618E77800F8EB4B /* InitializeSDKTests.swift */,
861865
4AA8076E1F794C1C008CD551 /* KeychainStoreTests.swift */,
862866
9194657724F16E330070296B /* ParseACLTests.swift */,
863-
7044C22C25C5E4E90011F6E7 /* ParseAnonymousCombineTests.swift */,
864867
70170A4D2656EBA50070C905 /* ParseAnalyticsTests.swift */,
865868
91CB9536265966DF0043E5D6 /* ParseAnanlyticsCombineTests.swift */,
869+
7044C22C25C5E4E90011F6E7 /* ParseAnonymousCombineTests.swift */,
866870
70A2D86A25B3ADB6001BEB7D /* ParseAnonymousTests.swift */,
867871
7044C24225C5EA360011F6E7 /* ParseAppleCombineTests.swift */,
868872
70C5502125B3D8F700B5DBC2 /* ParseAppleTests.swift */,
@@ -871,6 +875,7 @@
871875
916786EF259BC59600BB5B4E /* ParseCloudTests.swift */,
872876
7044C21F25C5E0160011F6E7 /* ParseConfigCombineTests.swift */,
873877
70D1BE0625BB2BF400A42E7C /* ParseConfigTests.swift */,
878+
91B40650267A66ED00B129CD /* ParseErrorTests.swift */,
874879
89899DB426045DC4002E2043 /* ParseFacebookCombineTests.swift */,
875880
89899CF32603CE9D002E2043 /* ParseFacebookTests.swift */,
876881
7044C1F825C5CFAB0011F6E7 /* ParseFileCombineTests.swift */,
@@ -1749,6 +1754,7 @@
17491754
70C5504625B40D5200B5DBC2 /* ParseSessionTests.swift in Sources */,
17501755
70110D5C2506ED0E0091CC1D /* ParseInstallationTests.swift in Sources */,
17511756
7016ED4025C4A25A00038648 /* ParseUserCombineTests.swift in Sources */,
1757+
91B40651267A66ED00B129CD /* ParseErrorTests.swift in Sources */,
17521758
705727B12593FF8800F0ADD5 /* ParseFileTests.swift in Sources */,
17531759
70BC0B33251903D1001556DB /* ParseGeoPointTests.swift in Sources */,
17541760
7003957625A0EE770052CB31 /* BatchUtilsTests.swift in Sources */,
@@ -1911,6 +1917,7 @@
19111917
70C5504825B40D5200B5DBC2 /* ParseSessionTests.swift in Sources */,
19121918
709B98572556ECAA00507778 /* ParseACLTests.swift in Sources */,
19131919
7016ED4225C4A25A00038648 /* ParseUserCombineTests.swift in Sources */,
1920+
91B40653267A66ED00B129CD /* ParseErrorTests.swift in Sources */,
19141921
705727BC2593FF8C00F0ADD5 /* ParseFileTests.swift in Sources */,
19151922
709B984F2556ECAA00507778 /* AnyCodableTests.swift in Sources */,
19161923
7003957825A0EE770052CB31 /* BatchUtilsTests.swift in Sources */,
@@ -1972,6 +1979,7 @@
19721979
70C5504725B40D5200B5DBC2 /* ParseSessionTests.swift in Sources */,
19731980
70F2E2BC254F283000B2EA5C /* ParseObjectTests.swift in Sources */,
19741981
7016ED4125C4A25A00038648 /* ParseUserCombineTests.swift in Sources */,
1982+
91B40652267A66ED00B129CD /* ParseErrorTests.swift in Sources */,
19751983
705727BB2593FF8B00F0ADD5 /* ParseFileTests.swift in Sources */,
19761984
70F2E2BD254F283000B2EA5C /* AnyDecodableTests.swift in Sources */,
19771985
7003957725A0EE770052CB31 /* BatchUtilsTests.swift in Sources */,

Sources/ParseSwift/Types/ParseError.swift

+26-2
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,25 @@ import Foundation
1212
An object with a Parse code and message.
1313
*/
1414
public struct ParseError: ParseType, Decodable, Swift.Error {
15+
/// The value representing the error from the Parse Server.
1516
public let code: Code
17+
/// The text representing the error from the Parse Server.
1618
public let message: String
19+
/// An error value representing a custom error from the Parse Server.
20+
public let otherCode: Int?
21+
init(code: Code, message: String) {
22+
self.code = code
23+
self.message = message
24+
self.otherCode = nil
25+
}
1726

1827
/// A textual representation of this error.
1928
public var localizedDescription: String {
20-
return "ParseError code=\(code.rawValue) error=\(message)"
29+
if let otherCode = otherCode {
30+
return "ParseError code=\(code.rawValue) error=\(message) otherCode=\(otherCode)"
31+
} else {
32+
return "ParseError code=\(code.rawValue) error=\(message)"
33+
}
2134
}
2235

2336
enum CodingKeys: String, CodingKey {
@@ -347,14 +360,25 @@ public struct ParseError: ParseType, Decodable, Swift.Error {
347360
a non-2XX status code.
348361
*/
349362
case xDomainRequest = 602
363+
364+
/**
365+
Error code indicating any other custom error sent from the Parse Server.
366+
*/
367+
case other
350368
}
351369
}
352370

353371
extension ParseError {
354372

355373
public init(from decoder: Decoder) throws {
356374
let values = try decoder.container(keyedBy: CodingKeys.self)
357-
code = try values.decode(Code.self, forKey: .code)
375+
do {
376+
code = try values.decode(Code.self, forKey: .code)
377+
otherCode = nil
378+
} catch {
379+
code = .other
380+
otherCode = try values.decode(Int.self, forKey: .code)
381+
}
358382
message = try values.decode(String.self, forKey: .message)
359383
}
360384

Tests/ParseSwiftTests/APICommandTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class APICommandTests: XCTestCase {
177177
let errorKey = "error"
178178
let errorValue = "yarr"
179179
let codeKey = "code"
180-
let codeValue = 100500
180+
let codeValue = 100
181181
let responseDictionary: [String: Any] = [
182182
errorKey: errorValue,
183183
codeKey: codeValue

Tests/ParseSwiftTests/ParseCloudTests.swift

+25
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,31 @@ class ParseCloudTests: XCTestCase { // swiftlint:disable:this type_body_length
356356
}
357357
}
358358

359+
func testCustomError() {
360+
361+
guard let encoded: Data = "{\"error\":\"Error: Custom Error\",\"code\":2000}".data(using: .utf8) else {
362+
XCTFail("Could not unwrap encoded data")
363+
return
364+
}
365+
366+
MockURLProtocol.mockRequests { _ in
367+
return MockURLResponse(data: encoded, statusCode: 200, delay: 0.0)
368+
}
369+
do {
370+
let cloud = Cloud(functionJobName: "test")
371+
_ = try cloud.runFunction()
372+
XCTFail("Should have thrown ParseError")
373+
} catch {
374+
if let error = error as? ParseError {
375+
XCTAssertEqual(error.code, .other)
376+
XCTAssertEqual(error.message, "Error: Custom Error")
377+
XCTAssertEqual(error.otherCode, 2000)
378+
} else {
379+
XCTFail("Should have thrown ParseError")
380+
}
381+
}
382+
}
383+
359384
func jobAsync(serverResponse: [String: String], callbackQueue: DispatchQueue) {
360385

361386
let expectation1 = XCTestExpectation(description: "Logout user1")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
//
2+
// ParseErrorTests.swift
3+
// ParseSwift
4+
//
5+
// Created by Corey Baker on 6/16/21.
6+
// Copyright © 2021 Parse Community. All rights reserved.
7+
//
8+
9+
import Foundation
10+
import XCTest
11+
@testable import ParseSwift
12+
13+
class ParseErrorTests: XCTestCase {
14+
15+
override func setUpWithError() throws {
16+
try super.setUpWithError()
17+
guard let url = URL(string: "http://localhost:1337/1") else {
18+
XCTFail("Should create valid URL")
19+
return
20+
}
21+
ParseSwift.initialize(applicationId: "applicationId",
22+
clientKey: "clientKey",
23+
masterKey: "masterKey",
24+
serverURL: url,
25+
testing: true)
26+
}
27+
28+
override func tearDownWithError() throws {
29+
try super.tearDownWithError()
30+
MockURLProtocol.removeAll()
31+
#if !os(Linux) && !os(Android)
32+
try KeychainStore.shared.deleteAll()
33+
#endif
34+
try ParseStorage.shared.deleteAll()
35+
}
36+
37+
func testEncode() throws {
38+
let code = -1
39+
let message = "testing ParseError"
40+
guard let encoded: Data = "{\"error\":\"\(message)\",\"code\":\(code)}".data(using: .utf8) else {
41+
XCTFail("Should have unwrapped")
42+
return
43+
}
44+
let decoded = try ParseCoding.jsonDecoder().decode(ParseError.self, from: encoded)
45+
XCTAssertEqual(decoded.code.rawValue, code)
46+
XCTAssertEqual(decoded.message, message)
47+
XCTAssertEqual(decoded.localizedDescription, "ParseError code=\(code) error=\(message)")
48+
}
49+
50+
func testEncodeOther() throws {
51+
let code = 2000
52+
let message = "testing ParseError"
53+
guard let encoded = "{\"error\":\"\(message)\",\"code\":\(code)}".data(using: .utf8) else {
54+
XCTFail("Should have unwrapped")
55+
return
56+
}
57+
let decoded = try ParseCoding.jsonDecoder().decode(ParseError.self, from: encoded)
58+
XCTAssertEqual(decoded.code, .other)
59+
XCTAssertEqual(decoded.message, message)
60+
XCTAssertEqual(decoded.localizedDescription,
61+
"ParseError code=\(ParseError.Code.other.rawValue) error=\(message) otherCode=\(code)")
62+
XCTAssertEqual(decoded.otherCode, code)
63+
}
64+
}

0 commit comments

Comments
 (0)