Form submission throws an unexpected error.
Unanswered
Shiloh Shepherd posted this in #help-forum
Shiloh ShepherdOP
I’m encountering an error in my Next.js application during production builds:
"An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error."
I have a server action where I am explicitely throwing the error based on a check. The client side catches the error and shows a toast, that works fine locally but, in the production build I get the above error.
"An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error."
I have a server action where I am explicitely throwing the error based on a check. The client side catches the error and shows a toast, that works fine locally but, in the production build I get the above error.
2 Replies
Shiloh ShepherdOP
Here is the server action code
export const createGoalForChannel = withSession(
async ({
brandId,
csrfToken,
goalMetric,
period,
startDate,
endDate,
channel,
goalValues,
specificPeriods,
initialStatus,
}: CreateGoalForChannelParams) => {
try {
const client = getSupabaseServerActionClient({ admin: true });
const { data: existingGoals } = await client
.from(GOAL_TABLE)
.select(
`
goal_id,
goal_metric,
`,
)
.eq('brand_id', brandId)
.eq('goal_metric', goalMetric)
.or('status.eq.ongoing,status.eq.scheduled');
const duplicateChannels = existingGoals?.some((goal) =>
goal.goal_channel.some((gc) => gc.channel_id === channel.channelId),
);
if (duplicateChannels) {
throw new Error(
`A goal for ${goalMetric} already exists for the following channels: ${channel.channel}`,
);
}
const { data: goalData, error: goalError } = await client
.from(GOAL_TABLE)
.insert({
brand_id: brandId,
metadata: {
progress_status: 'on_track',
},
})
.select('goal_id, status')
.single();
if (goalError || !goalData) {
throw new Error(`Failed to create goal: ${goalError?.message}`);
}
const { data: goalChannel, error: goalChannelError } = await client
.from(GOAL_CHANNEL_TABLE)
.insert({
goal_id: goalData.goal_id,
progress: 0,
})
.select('*, brand_channel!inner(channel,id)')
.single();
if (goalChannelError) {
throw new Error(
`Failed to create goal channel: ${goalChannelError.message}`,
);
}
return {
success: true,
goalId: {
...goalData,
goal_channel: [goalChannel],
},
};
} catch (e) {
throw e;
}
},
);
American black bear
Your error is not being passed from server to client because of security, as errors can contain sensitive information such as credentials or even env variables. If you want to fix this don't pass entire error object and instead pass custom status, error message and some error specific data if you need it.
export async function doSomething() {
try {
// do something which might throw an error
} catch (e) {
return {
ok: false,
status: 500,
error: e?.message ?? "Something went wrong"
}
}
}