Apollo iOS client - get http status code

Hi folks, is this possible?

Network.shared.apolloClient.perform(mutation: mutation) { result in
            switch result {
            case .success(_):
                callback(true)
            case .failure(let error):
                print(error)
                //how to get statusCode here? all i have is error.localizedDescription
                callback(false)
            }
        }

Hi! So a couple of things to be aware of here:

  • Generally, GraphQL returns a 200 OK even if there were errors if you’re able to actually get to the GraphQL server. In this case, any errors would actually come through the success block since that’s a graphQLResult that has both a data property and an errors array. In general, you shouldn’t need to directly check a status code with a canonical* GQL setup.

  • If there’s some kind of error prior to hitting your GQL server, that can be when you’ll actually get something back in the failure block that might have a status code you want to check (this is if the call even gets out to the network - this is also where you get errors on things like the user not being connected to the internet).

    This gets a little bit more involved - you’ll want to read some of our docs on advanced network setup with the request chain and interceptors, but the (very) shortened answer is that adding a custom additonalErrorHandler to a custom InterceptorProvider should help since that handler gets access to the response received from the server, including the status code, and you can check the code in that additionalErrorHandler.

* - In the real world, there is often middleware that checks your authentication info before you get passed into the GQL server, and this is where you can hit a 401 or other similar unauthorized error where you would need to check the status code

Hope this helps - let me know if there’s other stuff I can clarify! I do want to get a better example of some of this stuff up in the new year!

Thank you so much DN! This helped. I’ve updated our setup to pass additonalErrorInterceptor and it worked (we originally put this from older apollo example). If there is a better way of doing it, or is this a good approach in you opinion?

Also other issue we have, is we need to update it to use background URLSession, is there an example of that you can share please? In our app users do offline work, and it’s uploaded later in background, but default is standard session in apollo so we can’t move certain calls to apollo yet from REST because we haven’t figured out how to have apollo use background session with all the delegates.

Thank you,
Chris

P.S. This is our interceptor provider chain.

private func createClient() -> ApolloClient {
        let client = URLSessionClient()
        let cache = InMemoryNormalizedCache()
        let store = ApolloStore(cache: cache)
        let provider = NetworkInterceptorProvider(client: client, store: store)
        let transport = RequestChainNetworkTransport(interceptorProvider: provider,
                                                                     endpointURL: baseUrl!)
        networkTransport = transport
        mClient = ApolloClient(networkTransport: self.networkTransport, store: store)
        return mClient!
    }

class NetworkInterceptorProvider: LegacyInterceptorProvider {
        override func interceptors<Operation: GraphQLOperation>(for operation: Operation) -> [ApolloInterceptor] {
            var interceptors = super.interceptors(for: operation)
            interceptors.insert(TokenAddingInterceptor(), at: 0)
            return interceptors
        }
        
        override func additionalErrorInterceptor<Operation: GraphQLOperation>(for: Operation) -> ApolloErrorInterceptor? {
            return StatusCodeErrorInterceptor()
        }
    }

Yes, this is currently the way to set it up. Long-term, we’re looking to simplify this a bit, but that’s going to wait until we’ve got our updated code generation nailed down.

For the background URLSession, the initializer for URLSessionClient takes a URLSessionConfiguration as a parameter. You should receive that configuration as part of the notification that a background session has started.