fix(adapter-planetscale): propagate COMMIT errors in transactions#29155
Conversation
…ng them Fixes prisma#29138 When PlanetScale's vttablet kills a transaction server-side, the COMMIT failure was silently swallowed because `reject(error)` was called on an already-resolved Promise (resolved earlier via `resolve(txWrapper)`). Replace `return reject(error)` with `throw error` so that `txResultPromise` rejects, which propagates the error through `commit()` to the consumer.
WalkthroughFixes a critical bug in the PlanetScale adapter where transaction COMMIT errors were silently swallowed. Replaces the error rejection path with exception throwing in Changes
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 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 |
Merging this PR will degrade performance by 29.41%
Performance Changes
Comparing |
Problem
Fixes #29138
When PlanetScale's vttablet kills a transaction server-side (e.g., 20-second timeout),
@prisma/adapter-planetscalesilently swallows the COMMIT failure. Prisma resolves the operation as successful and returns data from the uncommitted transaction, but nothing is actually persisted. This causes silent data loss in production.Root Cause
In
startTransactionInner(), the outer Promise isresolve()d inside theconn.transaction()callback — before the transaction completes. When COMMIT later fails:.catch().catch()callsreject(error)— but the Promise is already resolved, so this is a no-op.catch()returnsundefined, sotxResultPromiseresolves successfullycommit()awaitstxResultPromise→ resolves → silent data lossFix
One-line change: replace
return reject(error)withthrow error.When we
throwinstead of calling the already-settledreject():txResultPromise(the.catch()chain result) rejects with the errorcommit()awaitstxResultPromise→ throws → error propagates to the consumerTests
Added 3 test cases:
commit succeeds when conn.transaction() resolves— no regression on happy pathcommit throws when conn.transaction() rejects after COMMIT failure— verifies the fixrollback does not throw (RollbackError is swallowed)— no regression on rollbackSummary by CodeRabbit
Bug Fixes
Tests