Reputation: 1
I have a database with some students for which I need to update the grades. I want to use Prisma transaction and an array of ids/grades to update all matching records in the database. All works fine until any ID is not found on the database in which case the whole transaction fails as expected but without information about which specific record caused the error.
What I want is to be able to throw a custom error specifiying the ID that wasn't found so I can alert the user.
Here's the code:
const grades = [
{id: 1, grade: '100'}
{id: 45, grade: '98' }
]
prisma.$transaction(
grades.map((el) => prisma.student.update({
where: { id: el.id },
data: { grade: el.grade }
})
)
This works until an id is not found on the database, in which case it throws an error like: Record not found.
The problem is that it doesn't tell me which ID is not found so I can alert the user.
I already tried putting a catch on every query so I can throw a custom error with the required info like so:
grades.map((el) => prisma.student.update({
where: { id: el.id },
data: { grade: el.grade }
}).catch((e) => throw new Error(`ID not found ${el.id}`)
)
This code throws the following type erorr and does not run:
Argument of type 'Promise<Student>[]' is not assignable to parameter of type 'PrismaPromise<any>[]'.
Type 'Promise<Student>' is not assignable to type 'PrismaPromise<any>'.
Property '[prisma]' is missing in type 'Promise<Student>' but required in type '{ [prisma]: true; }'.
How can I alert the user which specific ID's are not found?
Upvotes: 0
Views: 303
Reputation: 3238
Why not run a query before your transaction which attempts to load all the grades from the database before updating them? Then, you can compare the grades that were loaded from the database and, if there's a difference in the number of items, find the ones that are missing and throw an error.
const gradeIds = grades.map(grade => grade.id);
const dbGrades = await prisma.student.findMany({
// This only loads the ID from grades in the database to reduce
// the size of the query and only grab the necessary data
// for the operation
select: {id: true},
where: {id: {in: gradeIds}}
});
// If this condition is true, then some grades
// from the "grades" variable could not have been loaded.
// Figure out what those grades are and throw an error.
if (dbGrades.length !== grades.length) {
const dbGradeIds = dbGrades.map(dbGrade => dbGrade.id);
const missingGrades = gradeIds.filter(gradeId => dbGradeIds.indexOf(gradeId) === -1);
throw new Error(`ID(s) not found: ${missingGrades.join(",")}`);
}
// Else, the number of items is the same, and every input grade has a corresponding
// item in the database, therefore you should be able to do the update without
// having to worry about a missing item
Upvotes: 1