Skip to content

Is should be possible to retry a request from a HTTPInterceptor #3611

@andykent

Description

@andykent

Use case

Context: I am converting a bunch of legacy v1 interceptors over to v2. I've been enjoying it so far but have hit a slight snag.

In one specific case I am trying to migrate an interceptor that catches 401 errors, fetches new tokens and then retries them. I assumed this should be moved to a HTTPInterceptor as it is purely concerned with the HTTP layer and doesn't touch the GQL query.

The docs state:

When a RequestChain receives a thrown RequestChain.Retry error, it will restart from step 1 of the Request Chain Flow using the request provided by the error. This allows the request to be modified to correct errors that may be causing the failure prior to beginning again.

I assumed from this that I would be able to modify the URLRequest, throw RequestChain.Retry and have the whole chain retry. Unfortunately though RequestChain.Retry requires a GraphQLRequest not a URLRequest and don't think I have any access to the GraphQLRequest from within a HTTPInterceptor?

Is this an oversight in the API or is it that I am missing something obvious?

A simplified version of what I am trying to do is included below:

final class TokenAddingInterceptor: HTTPInterceptor {
  func intercept(request: URLRequest, next: @Sendable (URLRequest) async throws -> Apollo.HTTPResponse) async throws -> Apollo.HTTPResponse {
    let jwt = try await getToken()
    var newRequest = request
    newRequest.addValue("Bearer \(jwt.token)", forHTTPHeaderField: "Authorization")
    let response = try await next(newRequest)
    if response.response.statusCode == 401 {
      await refreshToken()
      throw RequestChain.Retry( ??? )
    }
    return response
  }
}

Describe the solution you'd like

I think either support should be added for retrying requests from HTTPInterceptor or the docs should be updated to make it clearer what parts of the RequestChain do and don't support retrying.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew addition or enhancement to existing solutions

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions