Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unique constraint error inside a transaction throws unparsed error (but works fine when using Node API) #7326

Closed
kripod opened this issue May 28, 2021 · 6 comments · Fixed by #8384
Labels
bug/2-confirmed Bug has been reproduced and confirmed. kind/bug A reported bug. team/client Issue for team Client. topic: error topic: $transaction Related to .$transaction(...) Client API topic: transaction
Milestone

Comments

@kripod
Copy link
Contributor

kripod commented May 28, 2021

Bug description

While trying to auto-generate slugs for user-made pages at Copyfolio, we noticed that unique constraint violation errors aren’t caught properly inside a prisma.$transaction.

How to reproduce

  1. Have a model with a unique constraint, e.g. a Site with a globally unique URL slug.

  2. Run some code which is meant to detect unique slug constraint violation errors – and then auto-generate a new slug to try with, but that isn’t part of the code below:

/* Fill our database with some initial data */
await prisma.site.create({ id: "1", slug: "taken-by-1" });
await prisma.site.create({ id: "2", slug: "another" });

try {
  await prisma.$transaction([
    prisma.site.updateMany({
      where: { id: "2" },
      data: { slug: "taken-by-1" },
    }),

    /* Any other site update is required for the test to fail */
    prisma.site.update({
      where: { id: "2" },
      data: { id: "2" },
    }),
  ]);
} catch (error) {
  if (
    error instanceof PrismaClientKnownRequestError &&
    error.code === "P2002"
  ) {
    console.debug("Unique constraint violation detection works");
  } else {
    console.error("Unknown error, as violation detection fails");
    throw error;
  }
}

It should throw an unknown error, which isn’t the expected behavior. However, then using previewFeatures = ["nApi"], the code above works as expected.

Expected behavior

No response

Prisma information

model Site {
  id   String @id @default(cuid())
  slug String @unique
}

Environment & setup

  • OS: mac OS v11.4
  • Database: PostgreSQL 12/13
  • Node.js version: v14.16.1

Prisma Version

prisma               : 2.23.0
@prisma/client       : 2.23.0
Current platform     : darwin
Query Engine         : query-engine adf5e8cba3daf12d456d911d72b6e9418681b28b (at node_modules/@prisma/engines/query-engine-darwin)
Migration Engine     : migration-engine-cli adf5e8cba3daf12d456d911d72b6e9418681b28b (at node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine : introspection-core adf5e8cba3daf12d456d911d72b6e9418681b28b (at node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary        : prisma-fmt adf5e8cba3daf12d456d911d72b6e9418681b28b (at node_modules/@prisma/engines/prisma-fmt-darwin)
Default Engines Hash : adf5e8cba3daf12d456d911d72b6e9418681b28b
Studio               : 0.393.0
@kripod kripod added the kind/bug A reported bug. label May 28, 2021
@pantharshit00
Copy link
Contributor

pantharshit00 commented May 28, 2021

I can reproduce this. Looks like we aren't serializing the error properly for child process + http version and it is properly serialized in the NAPI implementation.

We should fix this as NAPI is not stable yet.

@pantharshit00 pantharshit00 added process/candidate bug/2-confirmed Bug has been reproduced and confirmed. topic: node-api formerly `nApi` topic: error team/client Issue for team Client. labels May 28, 2021
@pantharshit00
Copy link
Contributor

pantharshit00 commented May 28, 2021

For internal reference:

Error thrown with child process + http bridge implementation:

code/reproductions/issue-7326 is 📦 v1.0.0 via  v14.17.0
❯ yarn start
yarn run v1.22.5
$ ts-node main.ts
Unknown error, as violation detection fails
(node:30316) UnhandledPromiseRejectionWarning: Error: Error occurred during query execution:
ConnectorError(ConnectorError { user_facing_error: Some(KnownError { message: "Unique constraint failed on the fields: (`slug`)", meta: Object({"target": Array([String("slug")])}), error_code: "P2002" }), kind: UniqueConstraintViolation { constraint: Fields(["slug"]) } })
    at C:\Users\harshit\code\reproductions\issue-7326\node_modules\@prisma\client\runtime\index.js:27807:19
    at processTicksAndRejections (internal/process/task_queues.js:95:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:30316) UnhandledPromiseRejectionWarning: Unhandled promise rejec
tion. This error originated either by throwing inside of an async func
tion without a catch block, or by rejecting a promise which was not ha
ndled with .catch(). To terminate the node process on unhandled promis
e rejection, use the CLI flag `--unhandled-rejections=strict` (see htt
ps://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejectio
n id: 1)(node:30316) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Terminate batch job (Y/N)?
^C

Error thrown with the NAPI implementation:

$ ts-node main.ts
Unique constraint violation detection works
(node:22544) UnhandledPromiseRejectionWarning: Error:
Invalid `prisma.site.updateMany()` invocation in
C:\Users\harshit\code\reproductions\issue-7326\main.ts:12:19

   9
  10 try {
  11   await prisma.$transaction([
→ 12     prisma.site.updateMany(
  Unique constraint failed on the fields: (`slug`)
    at cb (C:\Users\harshit\code\reproductions\issue-7326\node_modules\@prisma\client\runtime\index.js:35151:17)
    at async Promise.all (index 0)
    at main (C:\Users\harshit\code\reproductions\issue-7326\main.ts:11:5)
(Use `node --trace-warnings ...` to show where the warning was created)
(node:22544) UnhandledPromiseRejectionWarning: Unhandled promise rejec
tion. This error originated either by throwing inside of an async func
tion without a catch block, or by rejecting a promise which was not ha
ndled with .catch(). To terminate the node process on unhandled promis
e rejection, use the CLI flag `--unhandled-rejections=strict` (see htt
ps://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejectio
n id: 2)
(node:22544) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Done in 1.49s.

Notice the proper stack trace rather than the engine panic dump.

@matthewmueller
Copy link
Contributor

matthewmueller commented Jun 2, 2021

Just to clarify because it took me a couple reads.

  • This isn't a bug with NAPI, it's a problem with our existing protocol
  • We should fix this because NAPI is not yet the default
  • Even when NAPI is the default, we'll still keep the older protocol around

@janpio janpio changed the title Unique constraint error inside a transaction throws unparsed error – but works fine when using N-API Unique constraint error inside a transaction throws unparsed error (but works fine when using Node API) Jun 3, 2021
@janpio janpio removed the topic: node-api formerly `nApi` label Jun 3, 2021
@matthewmueller
Copy link
Contributor

Could this be related to: #6705?

@matthewmueller matthewmueller added topic: $transaction Related to .$transaction(...) Client API topic: transaction labels Jun 28, 2021
@Sytten
Copy link
Contributor

Sytten commented Jun 28, 2021

I would favour a breaking change in the http protocol vs a keeping a broken implementation around.

@millsp
Copy link
Member

millsp commented Jul 31, 2021

Hey @kripod, I'm so happy to see you here! This is fixed in the upcoming #8384

@millsp millsp added this to the 2.29.0 milestone Aug 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/2-confirmed Bug has been reproduced and confirmed. kind/bug A reported bug. team/client Issue for team Client. topic: error topic: $transaction Related to .$transaction(...) Client API topic: transaction
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants