#Error messages from convex mutations

4 messages · Page 1 of 1 (latest)

upbeat swift
#

What's the best way to properly show an error like this which is thrown from a mutation

  throw new Error(
    `You are not authorized`
  );

The user should see 'You are not authorized' in a toast

It should not include any other convex stack trace information like

dusky swiftBOT
#

Hi @upbeat swift. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Use ConvexError instead of Error, and then catch it on the client and read its data field. Convex will only send that data to the client, not the internal stack trace. [Application errors]

1. Throw a ConvexError in your mutation

// convex/myFunctions.ts
import { mutation } from "./_generated/server";
import { ConvexError } from "convex/values";

export const myMutation = mutation({
  args: {},
  handler: async (ctx, args) => {
    const identity = await ctx.auth.getUserIdentity();
    if (!identity) {
      throw new ConvexError("You are not authorized");
    }

    // ...
  },
});

ConvexError is designed for application errors and can carry structured data in error.data. [ConvexError class; Application errors]

2. Catch it on the client and show a toast

import { ConvexError } from "convex/values";
import { useMutation } from "convex/react";
import { api } from "@/convex/_generated/api";

function MyComponent() {
  const myMutation = useMutation(api.myFunctions.myMutation);

  const onClick = async () => {
    try {
      await myMutation({});
      // success toast if you want
    } catch (error) {
      const message =
        error instanceof ConvexError
          ? (error.data as string) // "You are not authorized"
          : "Unexpected error occurred";

      showToast(message); // your toast helper
    }
  };

  // ...
}
#

This way the user only sees "You are not authorized" in the toast, and any Convex stack trace stays out of the UI. [Application errors; Errors in mutations]

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