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

add a formatError option to apollo client #116

Open
the-vampiire opened this issue Jun 19, 2019 · 2 comments
Open

add a formatError option to apollo client #116

the-vampiire opened this issue Jun 19, 2019 · 2 comments
Labels
core Feature requests related to core functionality project-apollo-client (legacy) LEGACY TAG DO NOT USE

Comments

@the-vampiire
Copy link

problem
accessing useful error data supplied by the server is tedious and verbose. even just accessing error.message is permanently branded with "GraphQL error: <message>" prefix see this popular issue.

this means something as simple as passing error.message to a component will not be the actual message delivered by the server.

apollo client provides an error object with this shape:

{
  networkErrors,
  graphQLErrors,
}

maybe i am alone here but i find network errors to be much less common than graphql errors sent back by the server. and network errors usually mean something has happened that is unrecoverable until some more serious issue has been resolved.

graphql errors on the other hand need to be used to update client components and let the user know what went wrong. as per the spec these graphql errors are buried under the extensions (and extensions.exception) property of each GrapQLError.

currently consumption on the client looks like this. note that this digging needs to be performed in every single component that is trying to handle errors:

error.graphQLErrors[].extensions.<properties the client needs>

proposal
what do you think about allowing the apollo client user to define how they want their error object shaped by the time it reaches a consumer component? something analogous to the apollo server formatError option passed to ApolloClient (or apollo link? honestly im a bit confused about the line between the link and the client itself) during construction.

example usage

const client = new ApolloClient({
  link,
  cache,
// every error that is received by the client passes through this, just like apollo server
  formatError: (error) => { // optional, default to current behavior
// i am imagining this object is the same as received in onError of apollo-link-error
    const { message, graphQLErrors, operation } = error;
   
    if (operation.somethingElse) { return error }; // conditionally shape the object

// whatever is returned from formatError is the object received by consumer components as the error object 
    return {
      message: message.replace("GraphQL error: ", "").trim(),
      errors: graphQLErrors,
    };
  },
});
<Mutation>
{(mutate, mutationState) => {
  const { loading, error, data } = mutationState;

  console.log(error); // { message: "actual server message", errors: GraphQLError[] }
}}
</Mutation>

this is just one example. in general i think it would provide much more flexibility to apollo client users that want to utilize the errors their API send to them. i spent a lot of time properly handling errors / messages / extra context when things go wrong in the API and its a real chore to make use of that information client side.

if people dont want any customization they can get the default (current) behavior by just leaving formatError undefined.

@the-vampiire
Copy link
Author

for the record this formatError option is not exclusive to react-apollo that is just the example i used. anyone making use of the error object received from a query or mutation could have it passed through and shaped beforehand.

@chkp-michaelo
Copy link

chkp-michaelo commented Aug 25, 2020

We ended up hacking Apollo client and hooks because of this issue.
Our override for the query and mutate methods:
`
const { query, mutate } = client;

client.query = (...args) => query.apply(client, args).catch((e) => {
	throw parseError(e);
});

client.mutate = (...args) => mutate.apply(client, args).catch((e) => {
	throw parseError(e);
});

`

@jerelmiller jerelmiller added project-apollo-client (legacy) LEGACY TAG DO NOT USE core Feature requests related to core functionality labels Apr 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core Feature requests related to core functionality project-apollo-client (legacy) LEGACY TAG DO NOT USE
Projects
None yet
Development

No branches or pull requests

3 participants