fix(client): handle batched findUniqueOrThrow misses#29654
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
Summary by CodeRabbit
Walkthrough
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
✨ Simplify code
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Hi @aqrln, sorry for the direct tag. This PR touches the The required workflows are still awaiting maintainer approval. Could you approve the workflow run, or route this to the right reviewer? The targeted regression test passes locally with: pnpm --filter @prisma/client test:functional:code --adapter js_pg --runInBand 29638-concurrent-find-unique-or-throwThanks! |
| @@ -622,7 +626,9 @@ export class ClientEngine implements Engine { | |||
| } catch (err) { | |||
| results.push(err as Error) | |||
| rollback = true | |||
There was a problem hiding this comment.
I'm not sure it make sense to have the canContinueOnError being set outside the catch especially since we are processing a queries.every().
in the cases we do not catch an error it would process queries.every() pointlessly
| let txInfo: InteractiveTransactionInfo | undefined | |
| if (transaction?.kind === 'itx') { | |
| // If we are already in an interactive transaction we do not nest transactions | |
| } catch (err) { | |
| const canContinueOnError = | |
| transaction?.kind !== 'batch' && | |
| queries.every((query) => query.action === 'findUnique' || query.action === 'findUniqueOrThrow') | |
| results.push(err as Error) | |
| rollback = true |
Problem
Concurrent
findUniqueOrThrow()calls can be auto-batched by Prisma Client. When multiple records are missing in the same batch, only the first missing query rejects withP2025. Later missing queries can incorrectly resolve withundefined.This happens because the multi-batch path in
ClientEngine.requestBatch()stops collecting results after the first thrown error. As a result, the returned result array can be shorter than the original request batch, and DataLoader resolves the remaining slots asundefined.Fixes #29638
Solution
Continue collecting results for auto-batched unique reads (
findUnique/findUniqueOrThrow) outside explicit batch transactions. This preserves one result per request, so each missingfindUniqueOrThrow()call rejects correctly withP2025.Tests
Added a functional regression test for concurrent
findUniqueOrThrow()calls with multiple missing records.