Skip to content

withServerActionInstrumentation usage on production (Next) #17189

@alexis-fordg3

Description

@alexis-fordg3

Environment

SaaS (https://sentry.io/)

What are you trying to accomplish?

Hi there! First of all, I love Sentry, it's a marvelous tool, so thank you for making it :)

NOTE: I am purposefully triggering errors on this code to test the errors on our deployed dev env, I understand I am forcing an object "test" on our payload.

That aside, I've been trying to integrate Sentry in our application and I've ran into a few issues, not as Sentry related, but perhaps you can give me a hand with a use case. The problem is the following:

export async function submitWorkOrderWithTelemetry(
  values: createWorkOrderSchemaValues,
  backlogIds: number[]
) {
  return Sentry.withServerActionInstrumentation(
    "workOrderAction",
    { recordResponse: true },
    async () => {
      const parsed = createWorkOrderSchema.safeParse(values);

      if (!parsed.success) {
        throw new Error(`Invalid values passed, check the payload`);
      }
      const test = { id: 1 };

      const formData = { ...test, backlogIds };

      const response = await rawClient(`/work-order`, {
        method: "POST",
        body: JSON.stringify(formData),
      });

      const data = await response.json();

      if (!response.ok) {
        throw new Error(data.message);
      }

      return {
        success: true,
        workOrderId: data.id,
        message: "Work order created! Redirecting...",
      };
    }
  );

And in our frontend I do this with Sonner:

  const createWOAction = async (values: CreateWorkOrderDto) => {
    const promise = submitWorkOrderWithTelemetry(values, selectedBacklogIds);

    toast.promise(promise, {
      loading: "Creating work order...",
      success: (res) => {
        if (res.workOrderId) {
          router.push(`/dashboard/work-orders/${res.workOrderId}`);
        }

        return res.message;
      },
      error: (err) => {
        return err.message;
      },
    });

    await promise;
  };

While this works perfefctly fine on dev, this does not work on production due to:

An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details

I know this is because Next obfuscates the error unless you actually return a clean value like return message: hi, so I ended up doing:

      if (!parsed.success) {
        const err = new Error("Invalid values passed");
        Sentry.captureException(err, {
          tags: { reason: "zod validation failed second attempt" },
        });
        return { success: false, message: "Invalid input values" };
      }

And on the frontend I'm just doing this now:

    const response = await submitWorkOrderWithTelemetry(
      values,
      selectedBacklogIds
    );
    if (response.success) {
      router.push(`/dashboard/work-orders/${response.workOrderId}`);
      toast.success(response.message);
    } else {
      toast.error(response.message);
    }

This works correctly, and I get the Sentry event/exception recorded correctly. My question mostly revolves around, should I even be wrapping this with withServerActionInstrumentation? Since I'm manually capturing the exceptions, am I losing its benefits? And most importantly, if I'm not, how can I confirm this? I could not find as much information on the docs, but perhaps I missed some spot on the docs also.

I am totally open at me being the stupid one here and misunderstanding how to use the hook entirely, I'm only 6 months in as a dev, so I can be doing something wrong for sure.

Any tips would be greatly appreciated!

How are you getting stuck?

Not entirely stuck, I'm just curious how withServerActionInstrumentation works when manually capturing exceptions instead of throwing, thank you!

Where in the product are you?

Issues

Link

No response

DSN

No response

Version

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    Status

    No status

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions