diff --git a/Amplify/Categories/API/Response/GraphQLError.swift b/Amplify/Categories/API/Response/GraphQLError.swift index 2afe5e8c63..7d1d21f104 100644 --- a/Amplify/Categories/API/Response/GraphQLError.swift +++ b/Amplify/Categories/API/Response/GraphQLError.swift @@ -44,3 +44,5 @@ extension GraphQLError { public let column: Int } } + +extension GraphQLError: Error { } diff --git a/AmplifyPlugins/Core/AWSPluginsCore/Sync/PaginatedList.swift b/AmplifyPlugins/Core/AWSPluginsCore/Sync/PaginatedList.swift index b77a11cbb9..baa78bcd29 100644 --- a/AmplifyPlugins/Core/AWSPluginsCore/Sync/PaginatedList.swift +++ b/AmplifyPlugins/Core/AWSPluginsCore/Sync/PaginatedList.swift @@ -12,4 +12,29 @@ public struct PaginatedList: Decodable { public let items: [MutationSync] public let nextToken: String? public let startedAt: Int64? + + enum CodingKeys: CodingKey { + case items + case nextToken + case startedAt + } + + public init(from decoder: Decoder) throws { + let values = try decoder.container(keyedBy: CodingKeys.self) + let optimisticDecodedResults = try values.decode([OptimisticDecoded>].self, forKey: .items) + items = optimisticDecodedResults.compactMap { try? $0.result.get() } + nextToken = try values.decode(String?.self, forKey: .nextToken) + startedAt = try values.decode(Int64?.self, forKey: .startedAt) + } +} + + +fileprivate struct OptimisticDecoded: Decodable { + let result: Swift.Result + + init(from decoder: Decoder) throws { + result = Result(catching: { + try T(from: decoder) + }) + } } diff --git a/AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Sync/InitialSync/InitialSyncOperation.swift b/AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Sync/InitialSync/InitialSyncOperation.swift index 6785669c6f..e01f235b88 100644 --- a/AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Sync/InitialSync/InitialSyncOperation.swift +++ b/AmplifyPlugins/DataStore/Sources/AWSDataStorePlugin/Sync/InitialSync/InitialSyncOperation.swift @@ -216,11 +216,17 @@ final class InitialSyncOperation: AsynchronousOperation { let syncQueryResult: SyncQueryResult switch graphQLResult { + case .success(let queryResult): + syncQueryResult = queryResult + + case .failure(.partial(let queryResult, let errors)): + syncQueryResult = queryResult + errors.map { DataStoreError.api(APIError(errorDescription: $0.message, error: $0)) } + .forEach { dataStoreConfiguration.errorHandler($0) } + case .failure(let graphQLResponseError): finish(result: .failure(DataStoreError.api(graphQLResponseError))) return - case .success(let queryResult): - syncQueryResult = queryResult } let items = syncQueryResult.items