jeddeloh / rescript-apollo-client

ReScript bindings for the Apollo Client ecosystem
MIT License
127 stars 18 forks source link

RetryLink and OnError Handling issue #116

Closed jeong-sik closed 3 years ago

jeong-sik commented 3 years ago

Thanks to all of you, it's working well. By the way, I wonder if you have any plans to offer RetryLink . Otherwise, you need to check if the flow on this page is working properly now.

https://www.apollographql.com/docs/react/data/error-handling/#on-graphql-errors

The last time I tried it, f.apply() was giving me an undefined error.

May you be full of happiness, with sincerity.

jeddeloh commented 3 years ago

Sure, I can add RetryLink. I've been overwhelmed with other things, but should free up soon-ish. In the meantime, you're welcome to submit a PR.

Could you provide a little more information on the f.apply() error? This was occuring in the ErrorLink?

jfrolich commented 3 years ago

We have an RetryLink in our app, not sure how complete it is, but might be helpful:

module RetryLink = {
  // serverError is an Error instance with some extra props
  // see: https://github.com/apollographql/apollo-client/blob/master/src/link/utils/throwServerError.ts
  type serverError = {
    statusCode: int,
    response: Js.Json.t,
    result: Js.Json.t,
  }
  type delay = {
    initial: int,
    max: int,
    jitter: bool,
  }
  type attempts<'raw_t_variables> = {
    max: int,
    retryIf: (Js.Nullable.t<serverError>, ApolloClient.Types.Operation.t) => bool,
  }

  type options<'raw_t_variables> = {
    delay: delay,
    attempts: attempts<'raw_t_variables>,
  }

  @module("@apollo/client/link/retry") @new
  external make: options<'raw_t_variables> => ApolloClient.Link.t = "RetryLink"
}
jeong-sik commented 3 years ago

Could you provide a little more information on the f.apply() error? This was occuring in the ErrorLink?


let errorLink = ApolloClient.Link.ErrorLink.make(({
  networkError,
  graphQLErrors,
  operation,
  response,
  forward,
}) => {
  let _ = switch graphQLErrors {
  | Some(e') =>
    e'->Belt.Array.map(error => {
      error.extensions
      ->Belt.Option.map(ext => {
        ext
        ->Js.Dict.get("code")
        ->Belt.Option.map(code => {
          switch code->Js.Json.decodeString {
          | Some(code') =>
            switch code' {
            | "UNAUTHENTICATED" => // Do Some Retry
              forward(operation)->ignore
            | _ => ()
            }
          | None => ()
          }
        })
      })
      ->ignore

      handleGraphQLError(error)
    })
  | None => [()]
  }

  let _ = switch networkError {
  | Some(networkError') => handleNetworkError(networkError')
  | None => ()
  }

  let _ = switch response {
  | Some(response') => Js.log2("Error Link response", response')
  | None => ()
  }

  None
})

image

image

forward: operation => js->Js_.forward(operation->Operation.toJs), I'm not sure if this signature is correct in the upper part.

The error appears in the operation->forward->ignore part.

jeong-sik commented 3 years ago

We have an RetryLink in our app, not sure how complete it is, but might be helpful:

module RetryLink = {
  // serverError is an Error instance with some extra props
  // see: https://github.com/apollographql/apollo-client/blob/master/src/link/utils/throwServerError.ts
  type serverError = {
    statusCode: int,
    response: Js.Json.t,
    result: Js.Json.t,
  }
  type delay = {
    initial: int,
    max: int,
    jitter: bool,
  }
  type attempts<'raw_t_variables> = {
    max: int,
    retryIf: (Js.Nullable.t<serverError>, ApolloClient.Types.Operation.t) => bool,
  }

  type options<'raw_t_variables> = {
    delay: delay,
    attempts: attempts<'raw_t_variables>,
  }

  @module("@apollo/client/link/retry") @new
  external make: options<'raw_t_variables> => ApolloClient.Link.t = "RetryLink"
}

Good binding. Thanks to this, I was able to test the RetryLink . Thank you.

jeong-sik commented 3 years ago

f is Observable2 image

jeddeloh commented 3 years ago

RetryLink bindings available in #119