Database Integration with PrismaLesson 4.5
How to handle database errors and transactions in Prisma
Prisma error types, PrismaClientKnownRequestError, error codes, unique constraint handling, transactions, interactive transactions, rollback
Handling Known Errors
Prisma throws typed errors. Import the error class to handle specific cases:
import { PrismaClientKnownRequestError } from '@prisma/client/runtime/library'
export async function createUser(email: string) {
try {
return await prisma.user.create({ data: { email } })
} catch (e) {
if (e instanceof PrismaClientKnownRequestError) {
if (e.code === 'P2002') {
// Unique constraint violation
return { error: 'Email already exists' }
}
if (e.code === 'P2025') {
// Record not found (for update/delete)
return { error: 'User not found' }
}
}
throw e // Re-throw unexpected errors
}
}Transactions
Use prisma.$transaction when multiple operations must succeed or fail together:
// Transfer credits between users
await prisma.$transaction(async (tx) => {
const sender = await tx.user.update({
where: { id: senderId },
data: { credits: { decrement: amount } },
})
if (sender.credits < 0) {
throw new Error('Insufficient credits') // Triggers rollback
}
await tx.user.update({
where: { id: receiverId },
data: { credits: { increment: amount } },
})
})Interactive transactions receive a tx client — use it for all queries inside the callback. Throwing any error inside the callback automatically rolls back all changes. Never use the regular prisma client inside a transaction callback.
