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

GraphQLResultNormalizer doesn't match GraphQLResultReader's behavior when parsing nil value for optional fields #56

Closed
youj opened this issue Feb 10, 2017 · 1 comment
Labels
bug Generally incorrect behavior

Comments

@youj
Copy link

youj commented Feb 10, 2017

Hi,

I've been running into an issue where my GraphQL response includes an optional field with a null value cannot be parsed by GraphQLResultReader from cache. The Record entry created by GraphQLResultNormalizer has a nil value, which cannot be parsed by GraphQLResultReader.

In the following example GraphQL response, avatarThumbnailUrl is an optional string field, which has null value for this node.

{
	"data": {
		"node": {
			"supporters": {
				"edges": [{
					"node": {
						"avatarThumbnailUrl": null
					}
				}]
			}
		}
	}
}

In GraphQLResultNormalizer.swift at line 47

func didParseNull() {
    valueStack.append(nil)
  }

Upon parsing a nil value, the result normalizer pushes a nil value on the valueStack, which is set to the record's value for cacheKey at line 35

  func didResolve(field: Field, info: GraphQLResolveInfo) {
    path.removeLast()
    
    let value = valueStack.removeLast()
    
    let dependentKey = [currentRecord.key, field.cacheKey].joined(separator: ".")
    dependentKeys.insert(dependentKey)
    
    currentRecord[field.cacheKey] = value
    
    if recordStack.isEmpty {
      records.merge(record: currentRecord)
    }
  }

When parsing from cache, GraphQLResultReader tries to parse the optional field from the record using the optional function in JSON.swift at line 48.

func optional(_ optionalValue: JSONValue?) throws -> JSONValue? {
  guard let value = optionalValue else {
    throw JSONDecodingError.missingValue
  }
  
  if value is NSNull { return nil }
  
  return value
}

This function throws missingValue error if the value is nil.

I believe this is a bug because this behavior causes these type of GraphQL responses to be not readable from cache.

I found by changing the nil value that was pushed onto the valueStack in GraphQLResultNormalizer to NSNull(), it fixes the problem.

func didParseNull() {
    valueStack.append(NSNull())
  }
@martijnwalraven martijnwalraven added the bug Generally incorrect behavior label Feb 10, 2017
@martijnwalraven
Copy link
Contributor

@youj: Good catch! Thanks for going through the code and finding the root cause. Fixed on master, I'll release a new version as soon as the CI tests pass.

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

No branches or pull requests

2 participants