swift-graphql icon indicating copy to clipboard operation
swift-graphql copied to clipboard

ObjectDecodingError.unexpectedObjectType on nullable field

Open justvil opened this issue 2 years ago • 2 comments

Hi,

Upgraded to version 4.0.0 and having issues with one of my queries now.

Query code:

struct Recording {
    struct Analysis {
        let success: Bool
    }
    
    let id: String
    let recordingStartedAt: Int?
    let analysis: Analysis?
}

let analysisSelection = Selection.Analysis<Recording.Analysis> {
    let success = try $0.success()
    
    return Recording.Analysis(success: success)
}

let recordingSelection = Selection.Recording<Recording> {
    let id = try $0.id()
    let recordingStartedAt = try $0.recordingStartedAt()
    let analysis = try $0.analysis(selection: analysisSelection.nullable)
    
    return Recording(id: id,
                     recordingStartedAt: recordingStartedAt,
                     analysis: analysis)
}

let query = Selection.Query {
    try $0.getMyRecordings(selection: recordingSelection.nullable.list)
}

Raw query response looks like this:

"getMyRecordingsquery__mmn5vco4e5qa":
	[[
		"__typename": "Recording",
		"idrecording__mmn5vco4e5qa": "628fc124bb23b25b368474cf",
		"analysisrecording__mmn5vco4e5qa": <null>,
		"recordingStartedAtrecording__mmn5vco4e5qa": <null>
	]]

However, I'm receiving ObjectDecodingError.unexpectedObjectType (expected : "Dictionary", received : <null>) on .sink(receiveCompletion:). After some debugging it looks like it's caused by decoding "analysisrecording__mmn5vco4e5qa", the decoder still invokes analysisSelection even if the object is <null>.

Maybe I'm missing something here?

Thanks!

justvil avatar Sep 07 '22 07:09 justvil

I've faced with the same issue

Sundea avatar Sep 14 '22 15:09 Sundea

I've found that value of AnyCodable is Optional<Any> - some : <null> in that cases. It's not nil. So, instead of void, we receive a "value" while decoding and decoder fails

(lldb) po value
▿ Optional<Any>
  - some : <null>
 
(lldb) po value == nil
false
@frozen public struct AnyCodable: Codable {
    public let value: Any

    public init<T>(_ value: T?) {
        self.value = value ?? ()
    }
}

Sundea avatar Sep 14 '22 15:09 Sundea