Skip to content

Commit 50e001f

Browse files
authored
fix(api): add collection type casting in swift 5.7 (#3602)
* fix(api): add collection type casting in swift 5.7 * add unit test cases * add descriptions to test cases
1 parent 68c7eff commit 50e001f

File tree

3 files changed

+109
-1
lines changed

3 files changed

+109
-1
lines changed

AmplifyPlugins/API/Sources/AWSAPIPlugin/Operation/AWSGraphQLSubscriptionTaskRunner.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,31 @@ fileprivate func toAPIError<R: Decodable>(_ errors: [Error], type: R.Type) -> AP
378378
(hasAuthorizationError ? ": \(APIError.UnauthorizedMessageString)" : "")
379379
}
380380

381+
#if swift(<5.8)
382+
if let errors = errors.cast(to: AppSyncRealTimeRequest.Error.self) {
383+
let hasAuthorizationError = errors.contains(where: { $0 == .unauthorized})
384+
return APIError.operationError(
385+
errorDescription(hasAuthorizationError),
386+
"",
387+
errors.first
388+
)
389+
} else if let errors = errors.cast(to: GraphQLError.self) {
390+
let hasAuthorizationError = errors.map(\.extensions)
391+
.compactMap { $0.flatMap { $0["errorType"]?.stringValue } }
392+
.contains(where: { AppSyncErrorType($0) == .unauthorized })
393+
return APIError.operationError(
394+
errorDescription(hasAuthorizationError),
395+
"",
396+
GraphQLResponseError<R>.error(errors)
397+
)
398+
} else {
399+
return APIError.operationError(
400+
errorDescription(),
401+
"",
402+
errors.first
403+
)
404+
}
405+
#else
381406
switch errors {
382407
case let errors as [AppSyncRealTimeRequest.Error]:
383408
let hasAuthorizationError = errors.contains(where: { $0 == .unauthorized})
@@ -402,5 +427,5 @@ fileprivate func toAPIError<R: Decodable>(_ errors: [Error], type: R.Type) -> AP
402427
errors.first
403428
)
404429
}
405-
430+
#endif
406431
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
9+
import Foundation
10+
11+
@_spi(AmplifyAPI)
12+
extension Array where Element == Error {
13+
func cast<T>(to type: T.Type) -> [T]? {
14+
self.reduce([]) { partialResult, ele in
15+
if let partialResult, let ele = ele as? T {
16+
return partialResult + [ele]
17+
}
18+
return nil
19+
}
20+
}
21+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//
2+
// Copyright Amazon.com Inc. or its affiliates.
3+
// All Rights Reserved.
4+
//
5+
// SPDX-License-Identifier: Apache-2.0
6+
//
7+
8+
9+
import XCTest
10+
@testable @_spi(AmplifyAPI) import AWSAPIPlugin
11+
12+
class ArrayWithErrorElementExtensionTests: XCTestCase {
13+
14+
/**
15+
Given: errors with generic protocol type
16+
When: cast to the correct underlying concrete type
17+
Then: successfully casted to underlying concrete type
18+
*/
19+
func testCast_toCorrectErrorType_returnCastedErrorType() {
20+
let errors: [Error] = [
21+
Error1(), Error1(), Error1()
22+
]
23+
24+
let error1s = errors.cast(to: Error1.self)
25+
XCTAssertNotNil(error1s)
26+
XCTAssertTrue(!error1s!.isEmpty)
27+
XCTAssertEqual(errors.count, error1s!.count)
28+
}
29+
30+
/**
31+
Given: errors with generic protocol type
32+
When: cast to the wong underlying concrete type
33+
Then: return nil
34+
*/
35+
func testCast_toWrongErrorType_returnNil() {
36+
let errors: [Error] = [
37+
Error1(), Error1(), Error1()
38+
]
39+
40+
let error2s = errors.cast(to: Error2.self)
41+
XCTAssertNil(error2s)
42+
}
43+
44+
/**
45+
Given: errors with generic protocol type
46+
When: some of the elements failed to cast to the underlying concrete type
47+
Then: return nil
48+
*/
49+
50+
func testCast_partiallyToWrongErrorType_returnNil() {
51+
let errors: [Error] = [
52+
Error2(), Error2(), Error1()
53+
]
54+
55+
let error2s = errors.cast(to: Error2.self)
56+
XCTAssertNil(error2s)
57+
}
58+
59+
struct Error1: Error { }
60+
61+
struct Error2: Error { }
62+
}

0 commit comments

Comments
 (0)