fix(vendors): fix transaction timeout and misleading error on vendor delete

Increase the Prisma interactive transaction timeout from the default 5s
to 30s so that the four sequential nullification + delete queries complete
reliably on a seeded database (P2028 timeout was the root cause).

Wrap the transaction in a try/catch so that if a timeout does still occur
the user sees "Delete timed out — please try again." instead of an
unhandled 500 that previously manifested as the misleading "referenced in
submitted or active purchase orders" error message.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Hardik 2026-05-18 23:34:35 +05:30
parent 19029a5a77
commit d689ef8893

View file

@ -173,12 +173,23 @@ export async function deleteVendor(id: string): Promise<ActionResult> {
}); });
if (blocked) return { error: "Cannot delete: vendor is referenced in submitted or active purchase orders." }; if (blocked) return { error: "Cannot delete: vendor is referenced in submitted or active purchase orders." };
await db.$transaction(async (tx) => { try {
await tx.purchaseOrder.updateMany({ where: { vendorId: id, status: "DRAFT" }, data: { vendorId: null } }); await db.$transaction(
await tx.product.updateMany({ where: { lastVendorId: id }, data: { lastVendorId: null } }); async (tx) => {
await tx.productVendorPrice.deleteMany({ where: { vendorId: id } }); await tx.purchaseOrder.updateMany({ where: { vendorId: id, status: "DRAFT" }, data: { vendorId: null } });
await tx.vendor.delete({ where: { id } }); await tx.product.updateMany({ where: { lastVendorId: id }, data: { lastVendorId: null } });
}); await tx.productVendorPrice.deleteMany({ where: { vendorId: id } });
await tx.vendor.delete({ where: { id } });
},
{ timeout: 30000 },
);
} catch (err: unknown) {
const code = (err as { code?: string })?.code;
if (code === "P2028") {
return { error: "Delete timed out — please try again." };
}
throw err;
}
revalidatePath("/admin/vendors"); revalidatePath("/admin/vendors");
return { ok: true }; return { ok: true };