#What is the best approach to handle errors in convex?

10 messages · Page 1 of 1 (latest)

meager edge
#

@vestal fox

vestal foxBOT
#

Let me check the knowledge base for you. One moment! :books:

#

Sorry @meager edge, I seem to be having a bit of trouble. Don't worry though, I've pinged my support and they will try to fix me up! :technologist:

Perhaps try again in 15mins?

meager edge
#

I have a users table in which I am querying to get users by email, and I have added a try and catch block there to handle the error.

export const getUserByEmail = query({
  args: { email: v.string() },
  handler: async (ctx, { email }) => {
    try {
      const user = await ctx.db
        .query("users")
        .withIndex("email", (q) => q.eq("email", email))
        .unique();

      return user;
    } catch (error) {
      return null;
    }
  },
});

Now when I want to fetch the query in the client, I am calling it like this.

export const getUserByEmail = (email: string) => {
  return fetchQuery(api.users.getUserByEmail, {
    email,
  });
};

Is there a better way to handle errors? Or this sounds good? @vestal fox

vestal foxBOT
#

Let me check the knowledge base for you. One moment! :books:

#

In Convex, if your query function hits an error, the error will be sent to the client and thrown from your useQuery call site. The best way to handle these errors is with a React error boundary component (https://reactjs.org/docs/error-boundaries.html). Error boundaries allow you to catch errors thrown in their child component tree, render fallback UI, and send information about the error to your exception handling service.

Here is an example of how you can wrap your entire application in a single error boundary:

<StrictMode>  
 <ErrorBoundary>  
 <ConvexProvider client={convex}>  
 <App />  
 </ConvexProvider>  
 </ErrorBoundary>  
</StrictMode>

In this case, any error in any of your components will be caught by the boundary and render the same fallback UI. If you'd like to enable some portions of your app to continue functioning even if other parts hit errors, you can instead wrap different parts of your app in separate error boundaries.

Also, it's important to note that unlike other frameworks, there is no concept of "retrying" if your query function hits an error. Because Convex functions are deterministic, if the query function hits an error, retrying will always produce the same error. There is no point in running the query function with the same arguments again.

You can find more information about error handling in Convex in the official documentation (https://docs.convex.dev/functions/error-handling#errors-in-queries).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@meager edge kapa.ai is still learning and improving, please let us know how it did by reacting below

meager edge
#

So, it won't be caught on the try catch block under getUserByEmail in convex backend? @vestal fox

vestal foxBOT
#

Let me check the knowledge base for you. One moment! :books:

#

The try-catch block in your getUserByEmail function will catch any errors that occur within the try block. However, in your case, if the user is not found, it's not an error but rather a condition you need to handle. The try-catch block is more useful for catching unexpected errors or exceptions that occur during the execution of the code within the try block.

If the user is not found in the database, the ctx.db.query method will return null, and this is not an error but an expected result. Therefore, it won't be caught by the catch block.

If you want to handle the case where the user is not found, you should do it outside the try-catch block. For example:

export const getUserByEmail = query({
  args: { email: v.string() },
  handler: async (ctx, { email }) => {
    const user = await ctx.db
      .query("users")
      .withIndex("email", (q) => q.eq("email", email))
      .unique();

    if (!user) {
      // Handle the case where the user is not found
      // For example, throw a ConvexError
      throw new ConvexError("User not found");
    }

    return user;
  },
});

In this case, if the user is not found, a ConvexError will be thrown and this error can be caught and handled on the client side. You can find more information about handling errors in Convex in the official documentation (https://docs.convex.dev/functions/error-handling#errors-in-queries).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: