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

Error handling #202

Closed
mununki opened this issue Sep 10, 2020 · 9 comments
Closed

Error handling #202

mununki opened this issue Sep 10, 2020 · 9 comments

Comments

@mununki
Copy link

mununki commented Sep 10, 2020

Hi,

In case of having an error of GraphQLError from the gql api, the compiled query code throwing an error such as,

Uncaught TypeError: Cannot read property '__typename' of null
    at parse (Query.bs.js:27)
    at mapU (belt_Option.js:57)
    at Module.map (belt_Option.js:63)
    at Object.fromJs (ApolloClient__React_Types.bs.js:162)
    at eval (ApolloClient__React_Hooks_UseQuery.bs.js:52)
    at Module._1 (curry.js:51)
    at Module.useGuaranteedMemo1 (ApolloClient__Utils.bs.js:13)
    at useQuery (ApolloClient__React_Hooks_UseQuery.bs.js:51)
    at use (ApolloClient__React_Hooks_UseQuery.bs.js:72)
    at Module.app (curry.js:33)

I guess what it causes from this part of the compiled code.

module Ship = [%graphql
  {|
  query ship { shipRequests {
      id
      user_id
      species
      quantity
      created_at
    }
}
|}
];
function parse(value) {
  var value$1 = value.shipRequests; // throwing error!
  return {
          shipRequests: {
            __typename: value$1.__typename,
            id: value$1.id,
            user_id: value$1.user_id,
            species: value$1.species,
            quantity: value$1.quantity,
            created_at: value$1.created_at
          }
        };
}

In this case, Ship.use() alwasy throwing an error. I think this forces me to use the catching JS Exception which I am really not willing to use. Is there any workaround or a good way to avoid it?

@jfrolich
Copy link
Collaborator

Which client do you use? It's probably a client issue.

@jfrolich
Copy link
Collaborator

Ah from the error it looks like reason-apollo-client. Can you also share the schema? @jeddeloh

@jeddeloh
Copy link

Yeah, @mattdamon108, do you want to open an issue on reason-apollo-client? I only run data through the parse function if it's there, so this must be a case of having partial data. Coincidentally, I have a proposal out that would fix this issue: jeddeloh/rescript-apollo-client#45

In the meantime, maybe try setting your errorPolicy to None so you're not returning partial data along with errors?

  ApolloClient.(
    make(
      ~defaultOptions=
        DefaultOptions.make(
          ~query=
            DefaultQueryOptions.make(
              ~fetchPolicy=NetworkOnly,
              ~errorPolicy=None,
              (),
            ),
        ),
      ~cache=Cache.InMemoryCache.make(),
      ~link,
      (),
    )
  );

@mununki
Copy link
Author

mununki commented Sep 10, 2020

@jfrolich here's my query and schema

module Ship = [%graphql
  {|
  query { shipRequests {
      id
      user_id
      species
      quantity
      created_at
    }
}
|}
];
type Query {
  shipRequests: ship_request!
}

type ship_request {
  created_at: DateTime!
  id: Int!
  quantity: String!
  species: String!
  user_id: Int!
}

@mununki
Copy link
Author

mununki commented Sep 10, 2020

@jfrolich @jeddeloh I'm still not sure to what this issue belongs, the client.. or ppx..

According my schema, Query.shipRequests has a type ship_request!, it seems quite obvious that the function parse should looks like it. But, isn't it necessary to have a null checking inside?

function parse(value) {
  if(!value || !value.shipRequests) return  // something like this maybe?

  var value$1 = value.shipRequests;
  return {
          shipRequests: {
            __typename: value$1.__typename,
            id: value$1.id,
            user_id: value$1.user_id,
            species: value$1.species,
            quantity: value$1.quantity,
            created_at: value$1.created_at
          }
        };
}

@jfrolich
Copy link
Collaborator

What server do you use? It looks like value.shipRequests can never be null, is it violating the protocol? Or is it null because there are some errors?

@mununki
Copy link
Author

mununki commented Sep 10, 2020

@jfrolich I use apollo server with prisma. The case was caused by the authentication error actually. Yes, ship_request shouldn't be null so that I made a type in schema with !. But the case is happening in error handling side, before touching the ground to check the ship_request shouldn't be null with that parse function I guess.

let getUser = (req: ApolloServer.request) => {
  switch req.headers.authorization {
    | Some(authorization) => {
      try {
        authorization
        ->Js.String2.replace("Bearer ", "")
        ->verify(jwtSecret)
      } catch {
        | Js.Exn.Error(e) => {
          let name = e->Js.Exn.name->Belt.Option.getWithDefault("ErrorName")
          let message = e->Js.Exn.message->Belt.Option.getWithDefault("ErrorMessage")
          raise(ApolloServer.authenticationError(name ++ ": " ++ message))
        }
      }
    }
    | None => raise(ApolloServer.authenticationError("Authentication Required"))
  }
}

@jfrolich
Copy link
Collaborator

Yes if there is an error it's probably a bug in the client (it shouldn't try to parse the data).

@mununki
Copy link
Author

mununki commented Sep 11, 2020

@jfrolich fair enough. I opened an issue in client repo. And @jeddeloh mentioned there is upcomming PR to fix this. I'll close this issue. Thank you for your clarification and time.

@mununki mununki closed this as completed Sep 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants