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

If an error occurs during transaction, processing cannot continue #141

Closed
hokaccha opened this issue Mar 24, 2024 · 4 comments
Closed

If an error occurs during transaction, processing cannot continue #141

hokaccha opened this issue Mar 24, 2024 · 4 comments

Comments

@hokaccha
Copy link

When handling a unique constraint error, such as the following, executing a query after a unique constraint error occurs will result in an error.

// user.ts
import { PrismaClient } from "@prisma/client";

/**
 * Creates a user. Returns true if the creation succeeds or the user already exists.
 */
export async function ensureUser(
  prisma: PrismaClient,
  data: {
    id: number;
    name: string;
  }
): Promise<boolean> {
  try {
    await prisma.user.create({ data });
    return true;
  } catch (err: any) {
    const uniqConstraintFailed = err.code === "P2002";

    if (uniqConstraintFailed) {
      return true;
    } else {
      console.error(err);
      return false;
    }
  }
}
// user.test.ts
test("ensureUser", async () => {
  const data = { id: 1, name: "foo" };

  // succeed
  expect(await ensureUser(jestPrisma.client, data)).toBe(true);

  // succeed
  expect(await ensureUser(jestPrisma.client, data)).toBe(true);

  // fail
  expect(await jestPrisma.client.user.count()).toBe(1);
});
$ jest
 FAIL  ./app.test.ts
  User
    ✕ ensureUser (16 ms)

  ● User › ensureUser

    PrismaClientUnknownRequestError:
    Invalid `jestPrisma.client.user.count()` invocation in
    /path/to/app.test.ts:12:41

       9 const data = { id: 1, name: "foo" };
      10 expect(await ensureUser(jestPrisma.client, data)).toBe(true);
      11 expect(await ensureUser(jestPrisma.client, data)).toBe(true);
    → 12 expect(await jestPrisma.client.user.count(
    Error occurred during query execution:
    ConnectorError(ConnectorError { user_facing_error: None, kind: QueryError(PostgresError { code: "25P02", message: "current transaction is aborted, commands ignored until end of transaction block", severity: "ERROR", detail: None, column: None, hint: None }), transient: false })

I suspect this is due to PostgresSQL's limitation that if an error occurs during a transaction, subsequent queries cannot be issued.

@Quramy
Copy link
Owner

Quramy commented Mar 26, 2024

@hokaccha Thanks for your reporting.

I reproduced this message.

And I can suppress the 25P02 error using nested transaction like this:

/* user.test.ts */
test("ensureUser", async () => {
  const data = { id: 1, name: "foo" };

  // succeed
  expect(await ensureUser(jestPrisma.client, data)).toBe(true);

  try {
    await jestPrisma.client.$transaction(async () => {
      // succeed
      expect(await ensureUser(jestPrisma.client, data)).toBe(true);
      throw new Error();
    });
  } catch {}

  expect(await jestPrisma.client.user.count()).toBe(1);
});
/* jest.config.mjs */
export default {
  testEnvironment: "@quramy/jest-prisma-node/environment",
  testEnvironmentOptions: {
    enableExperimentalRollbackInTransaction: true, // Enable nested $transaction in test code
  },
};

Here is full example: https://github.com/Quramy/jest-prisma-repro-141/pull/1/files .

@hokaccha
Copy link
Author

And I can suppress the 25P02 error using nested transaction.

I see, it seems like this problem can be solved this way. Thank you.

@hokaccha
Copy link
Author

As far as I'm concerned, it's okay to close this issue, but I'll leave the decision up to you 🙏

@Quramy
Copy link
Owner

Quramy commented Mar 27, 2024

it's okay to close this issue, but I'll leave the decision up to you

Thanks. I'll write about this problem and the workaround to README's tips section.

Quramy added a commit that referenced this issue Mar 27, 2024
Quramy added a commit that referenced this issue Mar 27, 2024
Quramy added a commit that referenced this issue Mar 27, 2024
@Quramy Quramy closed this as completed Mar 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants