Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(client): Correctly report error location in batch transaction
Engine PR: prisma/prisma-engines#3384 Uses newly added `batch_request_idx` property of an errors to identify and correctly report error location within a batch. Fix #15433 Fix #14373
- Loading branch information
Showing
17 changed files
with
199 additions
and
46 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { hasBatchIndex } from '@prisma/engine-core' | ||
|
||
/** | ||
* Waits for result of batch $transaction and picks the best possible error to report if any | ||
* of the request fails. Best error is determined as follows: | ||
* | ||
* - if engine have reported and index of failed request in the batch, the best error is the one | ||
* who's index matches that | ||
* - otherwise, first error is used (like Promise.all) | ||
* | ||
* @param promises | ||
* @returns | ||
*/ | ||
export async function waitForBatch<T extends unknown[]>(promises: T): Promise<{ [K in keyof T]: Awaited<T[K]> }> { | ||
const results = await Promise.allSettled(promises) | ||
|
||
let bestError: unknown = null | ||
const successfulResults = [] as { [K in keyof T]: Awaited<T[K]> } | ||
for (const [i, result] of results.entries()) { | ||
if (result.status === 'rejected') { | ||
const reason = result.reason | ||
if (hasBatchIndex(reason) && reason.batchRequestIdx === i) { | ||
bestError = reason | ||
} else if (!bestError) { | ||
bestError = reason | ||
} | ||
} else { | ||
successfulResults.push(result.value) | ||
} | ||
} | ||
|
||
if (bestError) { | ||
throw bestError | ||
} | ||
return successfulResults | ||
} |
24 changes: 24 additions & 0 deletions
24
packages/client/tests/functional/issues/14373-batch-tx-error/_matrix.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
import { defineMatrix } from '../../_utils/defineMatrix' | ||
|
||
export default defineMatrix(() => [ | ||
[ | ||
{ | ||
provider: 'sqlite', | ||
}, | ||
{ | ||
provider: 'postgresql', | ||
}, | ||
{ | ||
provider: 'mysql', | ||
}, | ||
{ | ||
provider: 'mongodb', | ||
}, | ||
{ | ||
provider: 'cockroachdb', | ||
}, | ||
{ | ||
provider: 'sqlserver', | ||
}, | ||
], | ||
]) |
22 changes: 22 additions & 0 deletions
22
packages/client/tests/functional/issues/14373-batch-tx-error/prisma/_schema.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { idForProvider } from '../../../_utils/idForProvider' | ||
import testMatrix from '../_matrix' | ||
|
||
export default testMatrix.setupSchema(({ provider }) => { | ||
return /* Prisma */ ` | ||
generator client { | ||
provider = "prisma-client-js" | ||
} | ||
datasource db { | ||
provider = "${provider}" | ||
url = env("DATABASE_URI_${provider}") | ||
} | ||
model User { | ||
id ${idForProvider(provider)} | ||
email String @unique | ||
memo String? | ||
createdAt DateTime @default(now()) | ||
} | ||
` | ||
}) |
24 changes: 24 additions & 0 deletions
24
packages/client/tests/functional/issues/14373-batch-tx-error/tests.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
// @ts-ignore | ||
import type { PrismaClient } from '@prisma/client' | ||
|
||
import testMatrix from './_matrix' | ||
|
||
declare let prisma: PrismaClient | ||
|
||
testMatrix.setupTestSuite(() => { | ||
test('correctly reports location of a batch error', async () => { | ||
const result = prisma.$transaction([ | ||
prisma.user.findMany({}), | ||
prisma.user.update({ | ||
where: { | ||
email: 'notthere@example.com', | ||
}, | ||
data: { | ||
memo: 'id is 1', | ||
}, | ||
}), | ||
]) | ||
|
||
await expect(result).rejects.toThrowError('Invalid `prisma.user.update()` invocation') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7 changes: 7 additions & 0 deletions
7
packages/engine-core/src/common/errors/ErrorWithBatchIndex.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
export interface ErrorWithBatchIndex { | ||
batchRequestIdx?: number | ||
} | ||
|
||
export function hasBatchIndex(value: object): value is Required<ErrorWithBatchIndex> { | ||
return typeof value['batchRequestIdx'] === 'number' | ||
} |
15 changes: 13 additions & 2 deletions
15
packages/engine-core/src/common/errors/PrismaClientKnownRequestError.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
13 changes: 11 additions & 2 deletions
13
packages/engine-core/src/common/errors/PrismaClientUnknownRequestError.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.