Skip to content
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

"Optional is only JSONEncodable if Wrapped is" fatal error occurs on Optional #1271

Closed
ttrznadel opened this issue Jun 23, 2020 · 9 comments
Closed

Comments

@ttrznadel
Copy link

ttrznadel commented Jun 23, 2020

Apollo 0.28.0, SPM

fatal-error

case .some(let wrapped as JSONEncodable): fails, but
po self! as JSONEncodable works

If I add where Wrapped: JSONEncodable to Optional extension:
extension Optional: JSONEncodable where Wrapped: JSONEncodable { ... }
GraphQLExecutor.swift, line 232:

    if shouldComputeCachePath {
      let cacheKey = try firstField.cacheKey(with: info.variables)
      info.cacheKeyForField = cacheKey
      info.cachePath.append(cacheKey)
    }

Cannot convert value of type 'GraphQLMap?' (aka 'Optional<Dictionary<String, Optional>>') to expected argument type '[String : JSONEncodable]?'

Xcode 11.5, iOS 13 (simulator and device)

#0 0x00000001083989d7 in Optional.jsonValue.getter at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/JSONStandardTypeConversions.swift:109
#1 0x0000000108398a79 in protocol witness for JSONEncodable.jsonValue.getter in conformance A? ()
#2 0x000000010839931b in Dictionary.jsonObject.getter at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/JSONStandardTypeConversions.swift:123
#3 0x0000000108398b06 in Dictionary.jsonValue.getter at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/JSONStandardTypeConversions.swift:116
#4 0x0000000108399568 in protocol witness for JSONEncodable.jsonValue.getter in conformance [A : B] ()
#5 0x000000010839894c in Optional.jsonValue.getter at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/JSONStandardTypeConversions.swift:107
#6 0x0000000108398a79 in protocol witness for JSONEncodable.jsonValue.getter in conformance A? ()
#7 0x000000010839931b in Dictionary.jsonObject.getter at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/JSONStandardTypeConversions.swift:123
#8 0x0000000108398b06 in Dictionary.jsonValue.getter at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/JSONStandardTypeConversions.swift:116
#9 0x0000000108399568 in protocol witness for JSONEncodable.jsonValue.getter in conformance [A : B] ()
#10 0x0000000108395ca7 in static JSONSerializationFormat.serialize(value:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/JSONSerializationFormat.swift:5
#11 0x0000000108390663 in HTTPNetworkTransport.createRequest(for:files:httpMethod:sendQueryDocument:autoPersistQueries:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/HTTPNetworkTransport.swift:405
#12 0x000000010838f4fb in HTTPNetworkTransport.createRequest(for:isPersistedQueryRetry:files:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/HTTPNetworkTransport.swift:359
#13 0x000000010838c493 in HTTPNetworkTransport.send(operation:isPersistedQueryRetry:files:completionHandler:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/HTTPNetworkTransport.swift:151
#14 0x000000010839118d in HTTPNetworkTransport.send(operation:completionHandler:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/HTTPNetworkTransport.swift:440
#15 0x00000001083911a9 in protocol witness for NetworkTransport.send(operation:completionHandler:) in conformance HTTPNetworkTransport ()
#16 0x000000010a7a1e6f in ApolloClient.send(operation:shouldPublishResultToStore:context:resultHandler:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/ApolloClient.swift:70
#17 0x000000010a7a6cee in FetchQueryOperation.fetchFromNetwork() at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/ApolloClient.swift:287
#18 0x000000010a7a73c7 in closure #1 in FetchQueryOperation.start() at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/ApolloClient.swift:282
#19 0x000000010a7afeaf in closure #2 in ApolloStore.load(query:resultHandler:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/ApolloStore.swift:193
#20 0x000000010a80c70b in closure #1 in closure #1 in Promise.catch(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:142
#21 0x000000010a80f617 in partial apply for closure #1 in closure #1 in Promise.catch(
:) ()
#22 0x000000010a80febc in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#23 0x000000010a80ff2d in partial apply for thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#24 0x000000010a80eb8c in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> (@out ()) ()
#25 0x000000010a80eb3c in closure #1 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:223
#26 0x000000010a80ebaf in thunk for @callee_guaranteed () -> (@error @owned Error) ()
#27 0x000000010a80fbb4 in thunk for @callee_guaranteed () -> (@error @owned Error)partial apply ()
#28 0x000000010a800cb5 in Mutex.withLock
(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Locking.swift:29
#29 0x000000010a80e1c9 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:217
#30 0x000000010a80ab99 in Promise.reject(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:213
#31 0x000000010a80bf8d in closure #1 in closure #1 in Promise.andThen(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:128
#32 0x000000010a80f587 in partial apply for closure #1 in closure #1 in Promise.andThen(
:) ()
#33 0x000000010a80febc in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#34 0x000000010a80ff2d in partial apply for thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#35 0x000000010a80eb8c in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> (@out ()) ()
#36 0x000000010a80eb3c in closure #1 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:223
#37 0x000000010a80ebaf in thunk for @callee_guaranteed () -> (@error @owned Error) ()
#38 0x000000010a80fbb4 in thunk for @callee_guaranteed () -> (@error @owned Error)partial apply ()
#39 0x000000010a800cb5 in Mutex.withLock
(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Locking.swift:29
#40 0x000000010a80e1c9 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:217
#41 0x000000010a80ab99 in Promise.reject(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:213
#42 0x000000010a80cfd0 in closure #1 in closure #1 in Promise.map(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:168
#43 0x000000010a80f76d in partial apply for closure #1 in closure #1 in Promise.map
(:) ()
#44 0x000000010a80febc in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#45 0x000000010a80ff2d in partial apply for thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#46 0x000000010a80eb8c in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> (@out ()) ()
#47 0x000000010a80eb3c in closure #1 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:223
#48 0x000000010a80ebaf in thunk for @callee_guaranteed () -> (@error @owned Error) ()
#49 0x000000010a80fbb4 in thunk for @callee_guaranteed () -> (@error @owned Error)partial apply ()
#50 0x000000010a800cb5 in Mutex.withLock
(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Locking.swift:29
#51 0x000000010a80e1c9 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:217
#52 0x000000010a80ab99 in Promise.reject(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:213
#53 0x000000010a80c70b in closure #1 in closure #1 in Promise.catch(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:142
#54 0x000000010a80f617 in partial apply for closure #1 in closure #1 in Promise.catch(
:) ()
#55 0x000000010a80febc in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#56 0x000000010a80ff2d in partial apply for thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#57 0x000000010a80eb8c in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> (@out ()) ()
#58 0x000000010a80eb3c in closure #1 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:223
#59 0x000000010a80ebaf in thunk for @callee_guaranteed () -> (@error @owned Error) ()
#60 0x000000010a80fbb4 in thunk for @callee_guaranteed () -> (@error @owned Error)partial apply ()
#61 0x000000010a800cb5 in Mutex.withLock
(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Locking.swift:29
#62 0x000000010a80e1c9 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:217
#63 0x000000010a80ab99 in Promise.reject(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:213
#64 0x000000010a80bf8d in closure #1 in closure #1 in Promise.andThen(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:128
#65 0x000000010a80f587 in partial apply for closure #1 in closure #1 in Promise.andThen(
:) ()
#66 0x000000010a80febc in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#67 0x000000010a80ff2d in partial apply for thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#68 0x000000010a80eb8c in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> (@out ()) ()
#69 0x000000010a80eb3c in closure #1 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:223
#70 0x000000010a80ebaf in thunk for @callee_guaranteed () -> (@error @owned Error) ()
#71 0x000000010a80fbb4 in thunk for @callee_guaranteed () -> (@error @owned Error)partial apply ()
#72 0x000000010a800cb5 in Mutex.withLock
(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Locking.swift:29
#73 0x000000010a80e1c9 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:217
#74 0x000000010a80ab99 in Promise.reject(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:213
#75 0x000000010a80c70b in closure #1 in closure #1 in Promise.catch(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:142
#76 0x000000010a80f617 in partial apply for closure #1 in closure #1 in Promise.catch(
:) ()
#77 0x000000010a80ef5e in closure #1 in Promise.whenResolved(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:237
#78 0x000000010a80ebaf in thunk for @callee_guaranteed () -> (@error @owned Error) ()
#79 0x000000010a80f0d4 in partial apply for thunk for @callee_guaranteed () -> (@error @owned Error) ()
#80 0x000000010a800cb5 in Mutex.withLock
(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Locking.swift:29
#81 0x000000010a80b462 in Promise.whenResolved(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:231
#82 0x000000010a80c1c2 in closure #1 in Promise.catch(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:136
#83 0x000000010a80c1ff in partial apply for closure #1 in Promise.catch(:) ()
#84 0x000000010a80a7fa in Promise.init(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:68
#85 0x000000010a80907a in Promise.__allocating_init(:) ()
#86 0x000000010a808754 in Promise.catch(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:135
#87 0x000000010a80d65e in closure #1 in closure #1 in Promise.flatMap(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:180
#88 0x000000010a80f92d in partial apply for closure #1 in closure #1 in Promise.flatMap
(:) ()
#89 0x000000010a80febc in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#90 0x000000010a80ff2d in partial apply for thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#91 0x000000010a80eb8c in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> (@out ()) ()
#92 0x000000010a80eb3c in closure #1 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:223
#93 0x000000010a80ebaf in thunk for @callee_guaranteed () -> (@error @owned Error) ()
#94 0x000000010a80fbb4 in thunk for @callee_guaranteed () -> (@error @owned Error)partial apply ()
#95 0x000000010a800cb5 in Mutex.withLock
(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Locking.swift:29
#96 0x000000010a80e1c9 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:217
#97 0x000000010a80aa58 in Promise.fulfill(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:209
#98 0x000000010a80cf06 in closure #1 in closure #1 in Promise.map(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:163
#99 0x000000010a80f76d in partial apply for closure #1 in closure #1 in Promise.map
(:) ()
#100 0x000000010a80febc in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#101 0x000000010a80ff2d in partial apply for thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> () ()
#102 0x000000010a80eb8c in thunk for @escaping @callee_guaranteed (@in_guaranteed Result<A, Error>) -> (@out ()) ()
#103 0x000000010a80eb3c in closure #1 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:223
#104 0x000000010a80ebaf in thunk for @callee_guaranteed () -> (@error @owned Error) ()
#105 0x000000010a80fbb4 in thunk for @callee_guaranteed () -> (@error @owned Error)partial apply ()
#106 0x000000010a800cb5 in Mutex.withLock
(:) at /SourcePackages/checkouts/apollo-ios/Sources/Apollo/Locking.swift:29
#107 0x000000010a80e1c9 in Promise.resolve(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:217
#108 0x000000010a80aa58 in Promise.fulfill(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:209
#109 0x000000010a7bbc1c in thunk for @escaping @callee_guaranteed (@in_guaranteed B) -> () ()
#110 0x000000010a7bbd84 in partial apply for thunk for @escaping @callee_guaranteed (@in_guaranteed B) -> () ()
#111 0x000000010a7bcc0c in thunk for @escaping @callee_guaranteed (@in_guaranteed B) -> (@out ()) ()
#112 0x000000010a7bdfbe in closure #3 in closure #1 in DataLoader.dispatch() at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/DataLoader.swift:54
#113 0x000000010a7be0b2 in thunk for @escaping @callee_guaranteed (@guaranteed [B]) -> (@error @owned Error) ()
#114 0x000000010a7be166 in partial apply for thunk for @escaping @callee_guaranteed (@guaranteed [B]) -> (@error @owned Error) ()
#115 0x000000010a80be96 in closure #1 in closure #1 in Promise.andThen(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:122
#116 0x000000010a80f587 in partial apply for closure #1 in closure #1 in Promise.andThen(
:) ()
#117 0x000000010a80ef5e in closure #1 in Promise.whenResolved(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:237
#118 0x000000010a80ebaf in thunk for @callee_guaranteed () -> (@error @owned Error) ()
#119 0x000000010a80f0d4 in partial apply for thunk for @callee_guaranteed () -> (@error @owned Error) ()
#120 0x000000010a800cb5 in Mutex.withLock
(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Locking.swift:29
#121 0x000000010a80b462 in Promise.whenResolved(:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:231
#122 0x000000010a80bbf2 in closure #1 in Promise.andThen(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:118
#123 0x000000010a80bc2f in partial apply for closure #1 in Promise.andThen(:) ()
#124 0x000000010a80a7fa in Promise.init(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:68
#125 0x000000010a80907a in Promise.__allocating_init(:) ()
#126 0x000000010a8085a4 in Promise.andThen(
:) at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/Promise.swift:117
#127 0x000000010a7bc59c in closure #1 in DataLoader.dispatch() at xxx/SourcePackages/checkouts/apollo-ios/Sources/Apollo/DataLoader.swift:52
#128 0x000000010a7a6080 in thunk for @escaping @callee_guaranteed () -> () ()

@designatednerd
Copy link
Contributor

@ttrznadel - can you try pulling off main and see if this issue still occurs? #1262 should be a fix for this.

@ttrznadel
Copy link
Author

ttrznadel commented Jun 26, 2020

@designatednerd - I tried main, and the fatal error still occurs :/
I'm using now Cathage and everything works.

@designatednerd
Copy link
Contributor

That...is weird, the package manager shouldn't matter in this case. Is it working with Carthage off main or off 0.28.0?

@ttrznadel
Copy link
Author

Carthage of 0.28.0
That is weird for me too.

@designatednerd
Copy link
Contributor

@ttrznadel OK - I'll keep an eye out for this one but particulary with the changes in #1262 that should fix a large number of these issues going forward. Do you mind if we close this out?

@ttrznadel
Copy link
Author

@designatednerd OK, at this moment l'm using Carthage. I will try SPM again with new version release.

@designatednerd
Copy link
Contributor

Version 0.29.0 has been released with what should be a fix for this. I'm going to close this issue - please open a new issue referencing this one if you're still having problems with the new version. Thank you!

@ttrznadel
Copy link
Author

ttrznadel commented Jul 9, 2020

@designatednerd, @nateirwin
My problem occurs because I use Apollo (via SPM as static) in two targets. My GraphQL operation definitions and theirs execution were performed by another Apollo instances. Which Apollo instance will be used is non-deterministic.
I used DISABLE_DIAMOND_PROBLEM_DIAGNOSTIC flag - so the problem was hidden.

My temporary/test working solution was to fork Apollo framework and make package dynamic.

let package = Package(
    name: "Apollo",
    products: [
    .library(
      name: "ApolloCore",
      targets: ["ApolloCore"]),
    .library(
      name: "Apollo",
      type: .dynamic, //<---------------------
      targets: ["Apollo"]),
    .library(
      name: "ApolloCodegenLib",
      targets: ["ApolloCodegenLib"]),
    .library(
        name: "ApolloSQLite",
        targets: ["ApolloSQLite"]),
    .library(
        name: "ApolloWebSocket",
        targets: ["ApolloWebSocket"]),
    ],
    ...

@designatednerd
Copy link
Contributor

designatednerd commented Jul 9, 2020

The recommended workaround for using Apollo in multiple targets in the same project is to use one framework that imports Apollo, then have other targets import that framework. That way there's only one instance.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants