Ad

Cannot Receive Error From GraphQL With Graphql-middleware-sentry

Note: The problem was in graphql-middleware-sentry not forwarding on the errors. The solution is below and marked as the correct answer.

I'm currently handling a form using React and Apollo React Hooks on the frontend, and a mixture of GraphQL-Yoga and Prisma on the backend. The mutation works fine, and the form is ok. But I cannot receive errors thrown by the backend in React.

I've tried various error types but I haven't had much luck. For example, my mutation in react looks like this:

 const [requestPasswordResetMutation, { data, error, loading }] = useMutation(
    REQUEST_PASSWORD_REQUEST,
    {
      errorPolicy: 'all',
    },
  )

On the backend, I might want to throw an error where an email address isn't recognised. I run a simple check such as:

if (!user) {
    throw Error('User not found')
  }

This error is successfully triggered and picked up by Sentry. But no error is detected by the frontend in the errors variable. Instead, the form acts as though it is successfully submitted (given the absence of values in the errors object.

Can anyone give me a pointer on how I'm meant to be communicating errors from the backend to the frontend here?

Resolver code:

const requestPasswordReset = async (parent, { email }, context) => {
  const user = await context.prisma.user({
    email,
  })

  if (!user) {
    throw new Error('User not found')
  }

  const passwordResetToken = crypto.randomBytes(20).toString('hex')
  const passwordTokenExpiry = expiryDate()

  try {
    await context.prisma.updateUser({
      data: {
        passwordResetToken,
        passwordTokenExpiry,
      },
      where: {
        email: user.email,
      },
    })
  } catch (error) {
    console.error(error)
  }

  if (process.env.NODE_ENV === 'production') {
    // Send email
  }

  return {
    message: 'Reset token sent',
  }
}
Ad

Answer

graphql-middleware-sentry has a forwardErrors parameter that is false by default. You should set it to true in order to prevent it from swallowing the errors you throw:

const sentryMiddleware = sentry({
  forwardErrors: true,
  ...
})
Ad
source: stackoverflow.com
Ad