Apollo iOS Remove Potential PII from GraphQLResultError JSONDecodingError.couldNotConvert

Hello! Currently, in apollo-ios on the most up-to-date release (0.51.2) my team and I are running into an issue that we’re hoping can have an official solution instead of a fork we maintain.

The issue we’re experiencing has to do with logging errors our users run into. In the case there’s a decoding issue where a specific path in the Response could not convert to some type, a JSONDecodingError.couldNotConvert error is thrown which includes the value and the type it failed to convert into.

This is then wrapped within a GraphQLResultError type which includes the path to the key with the decoding issue.

With these two pieces together, we can potentially run into issues like the following being logged:

Error at path “accountHolder.birthDate)”: couldNotConvert(value: 2000-01-01T00:00:00.000Z, to: Foundation.Date)

The solution we started off with was to take the result from our queries or mutations and map the result’s error where the underlying type was JSONDecodingError.couldNotConvert to a new error of the same type but replacing value with "{private}" when in a Production Release configuration.

The issue with this approach is that we now lose the GraphQLResultError path information which is quite important to us in quickly determining issues in production. We also can’t create a new one of these objects because both the GraphQLResultError’s initializer and the path’s ResponsePath type are not public. Additionally, we can’t just replace the underlying Error type with our new PII-stripped version because it’s defined as a constant.

The lowest-impact approach we’ve landed on is:

  1. fork the Apollo iOS repo
  2. make the ResponsePath type and its description publicly accessible
  3. create our own representation of GraphQLResultError that we’ll map to in this situation where we can provide the PII-stripped JSONDecodingError and the Apollo-provided GraphQLResultError path information as a String

Is there a better approach to stripping potential PII? I’m also happy to contribute back if this is something that makes sense for the library to enable.

What we actually did instead was the following:

  1. Forked the repo over at GitHub - joshuashroyer-toast/apollo-ios: 📱  A strongly-typed, caching GraphQL client for iOS, written in Swift. and created a branch jshroyer/toast-updates for our changes.
  2. Added a public computed property to GraphQLResultError called pathString which is just the String representation using the already-defined description property from CustomStringConvertible

i.e. The GraphQLResultError now looks like this on our fork:

/// An error which has occurred in processing a GraphQLResult
public struct GraphQLResultError: Error, LocalizedError {
  let path: ResponsePath

  public var pathString: String { path.description }

  /// The error that occurred during parsing.
  public let underlying: Error

  /// A description of the error which includes the path where the error occurred.
  public var errorDescription: String? {
    return "Error at path \"\(path))\": \(underlying)"

We decided this would be the least intrusive changes that allow us to strip PII without losing fidelity of the generated Error. When in this circumstance, we map to our own Error types using the now-available information.