Home > OS >  React-query mutation isError not setting true on failed POST
React-query mutation isError not setting true on failed POST

Time:04-18

I am using the following fetch post request to create an item in my DB. I am trying to use react-query to detect the error thrown by the request.

export function createItem(id, body, token) {
  fetch(`${API_URL}/${id}/items`, {
    method: 'post',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
    body: JSON.stringify(body)
  })
    .then(res => {
      if (res.ok) {
        return res.json()
      }

      console.log(res.status)

      throw new Error("Error creating review")
    })
    .catch((err) => console.log(err))
}

I have the mutation set like so:

const mutation = useMutation(() => {
    return createItem(props.item.id, item, token)
})

And its called with:

<Button disabled={!valid} onPress={() => mutation.mutate()}>
    Submit
</Button>

I use this logic to display the error:

{
   mutation.isError && <Text>{mutation.error.message}</Text>
}

I see the createItem function errors with a 400 status code which is what I expect but react-query does not set isError to true. Instead isSuccess is true. Am I handling the error wrong some how?

CodePudding user response:

From the react query docs, they return a promise to the mutation, so try to change your function createItem to the following:

export function createItem(id, body, token) {
  // return the fetch as a promise
  return fetch(`${API_URL}/${id}/items`, {
    method: 'post',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
    body: JSON.stringify(body)
  })
  // remove then and catch here

CodePudding user response:

The problem is that you are catching the error inside the mutation function. React Query requires to you to return a resolved or rejected promise from your function.

Promise.catch also returns a Promise. If you don't return anything, it will be a Promise that returns undefined. But that is still a resolved Promise that will be passed to React Query.

So, in short: Don't catch inside the function. Use one of the callbacks that react-query provides for error logging:

export function createItem(id, body, token) {
  fetch(`${API_URL}/${id}/items`, {
    method: 'post',
    headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${token}` },
    body: JSON.stringify(body)
  })
    .then(res => {
      if (res.ok) {
        return res.json()
      }

      console.log(res.status)

      throw new Error("Error creating review")
    })
}
const mutation = useMutation(
  () => {
    return createItem(props.item.id, item, token)
  },
  {
    one rror: (error) => console.log(error)
  }
)
  • Related