Skip to content

fix(client-engine-runtime): populate standard meta fields in rethrowAsUserFacing#29349

Open
Yashsingh045 wants to merge 5 commits intoprisma:mainfrom
Yashsingh045:fix/mysql-p2002-meta-target
Open

fix(client-engine-runtime): populate standard meta fields in rethrowAsUserFacing#29349
Yashsingh045 wants to merge 5 commits intoprisma:mainfrom
Yashsingh045:fix/mysql-p2002-meta-target

Conversation

@Yashsingh045
Copy link

@Yashsingh045 Yashsingh045 commented Mar 18, 2026

This PR fixes issue #29344 where MySQL unique constraint violations (P2002) were missing the meta.target field when using driver adapters.

Changes

  • Updated packages/client-engine-runtime/src/user-facing-error.ts to extract standard Prisma metadata from DriverAdapterError.
  • Populated meta.target for UniqueConstraintViolation (P2002) and NullConstraintViolation (P2011).
  • Populated meta.field_name for ForeignKeyConstraintViolation (P2003).

Verification

  • Verified the fix with a manual script mocking various database error scenarios.
  • Ran all 91 unit tests in @prisma/client-engine-runtime. All tests passed.

Summary by CodeRabbit

  • Bug Fixes

    • Consolidated and enriched error metadata for database constraint violations so unique, null, and foreign-key errors include clearer, more consistent fields (e.g., target and field_name when available).
  • Tests

    • Added a functional test matrix, provider-driven schema, and tests covering unique (P2002), foreign-key (P2003), and null (P2011) constraint scenarios across SQL providers to validate the metadata.

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: d38a50b2-55e2-4de1-9ea0-f4aeed0872e2

📥 Commits

Reviewing files that changed from the base of the PR and between 656748b and bf044d6.

📒 Files selected for processing (2)
  • packages/client-engine-runtime/src/user-facing-error.ts
  • packages/client/tests/functional/issues/29344-adapter-constraint-meta/tests.ts

Walkthrough

Replaced inline driver-adapter error meta with a centralized getErrorMeta() in the client engine runtime and added a functional test matrix, schema, and tests that validate constraint error meta (unique, foreign-key, null) across SQL providers.

Changes

Cohort / File(s) Summary
Error metadata consolidation
packages/client-engine-runtime/src/user-facing-error.ts
Added getErrorMeta(err) to construct meta (always includes driverAdapterError; adds target for Unique/Null constraint violations and field_name for ForeignKey violations). Replaced inline { driverAdapterError: error } with getErrorMeta(error) in rethrow paths.
Functional test matrix
packages/client/tests/functional/issues/29344-adapter-constraint-meta/_matrix.ts
Added test matrix exporting SQL providers to run the new tests across SQL backends.
Test Prisma schema
packages/client/tests/functional/issues/29344-adapter-constraint-meta/prisma/_schema.ts
Added provider-aware test schema via testMatrix.setupSchema(...) defining User and Post models with provider-specific ID/foreign-key helpers.
Constraint meta tests
packages/client/tests/functional/issues/29344-adapter-constraint-meta/tests.ts
Added tests asserting error code and presence/shape of meta.target or meta.field_name for P2002, P2003, and P2011; includes provider-specific conditional assertions and MongoDB opt-out.

Possibly related issues

  • Mysql p2002 does not provide meta.target #29344 — Implements getErrorMeta(err) that normalizes constraint metadata (uses constraint.fields or constraint.index for target, and sets field_name for FK errors), aligning with the issue's objective.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: populating standard meta fields in the rethrowAsUserFacing function for driver adapter errors.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@Yashsingh045
Copy link
Author

Hey @nurul3101 ,
Could you please review this PR when you have time?
Thanks

Copy link
Contributor

@jacek-prisma jacek-prisma left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this deserves a regression test, you could have a look at packages/client/tests/functional/issues/29309-datetime-cursor for reference

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 9d9d738f-f233-440b-921a-ab36425ac2b3

📥 Commits

Reviewing files that changed from the base of the PR and between 4171c82 and c432f65.

📒 Files selected for processing (3)
  • packages/client/tests/functional/issues/29344-adapter-constraint-meta/_matrix.ts
  • packages/client/tests/functional/issues/29344-adapter-constraint-meta/prisma/_schema.ts
  • packages/client/tests/functional/issues/29344-adapter-constraint-meta/tests.ts

Comment on lines +21 to +24
expect(e.code).toBe('P2002')
expect(e.meta).toBeDefined()
expect(e.meta.target).toBeDefined()
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add name assertions to match functional test error assertion standards.

The catches assert code, but the suite rule for functional tests expects asserting both error name and code.

💡 Proposed fix
       } catch (e: any) {
+        expect(e.name).toBe('PrismaClientKnownRequestError')
         expect(e.code).toBe('P2002')
         expect(e.meta).toBeDefined()
         expect(e.meta.target).toBeDefined()
       }
@@
       } catch (e: any) {
+        expect(e.name).toBe('PrismaClientKnownRequestError')
         expect(e.code).toBe('P2003')
         expect(e.meta).toBeDefined()
         if (suiteConfig.provider !== Providers.SQLITE && suiteConfig.provider !== Providers.SQLSERVER) {
           expect(e.meta.field_name).toBeDefined()
         }
       }
@@
   if (caught.code === 'P2011') {
+    expect(caught.name).toBe('PrismaClientKnownRequestError')
     expect(caught.meta).toBeDefined()
     expect(caught.meta.target).toBeDefined()
   }
As per coding guidelines "`**/packages/client/tests/functional/**/*.ts`: In client functional tests, use `result.name === 'PrismaClientKnownRequestError'` and `result.code` for error assertions, not `instanceof`."

Also applies to: 34-38, 52-55

Comment on lines +42 to +56
test('P2011: NullConstraintViolation has meta.target', async () => {
// P2011 is not easy to trigger with Prisma abstractions if the field is typed as non-nullable
// We can use $executeRaw instead to insert a null optionally if the driver allows
// However, we just cover it using a raw query
try {
await prisma.$executeRaw`INSERT INTO "User" ("email") VALUES (NULL)`
} catch (e: any) {
// Some adapters might throw different errors for raw queries compared to client queries,
// but if it throws P2011 it should have meta.target.
// We'll optionally ignore it if the code isn't P2011.
if (e.code === 'P2011') {
expect(e.meta).toBeDefined()
expect(e.meta.target).toBeDefined()
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

P2011 test is currently non-assertive for the common raw-query path.

At Line 52, assertions run only when e.code === 'P2011', but raw adapter errors are mapped via the raw path and commonly surface as P2010. The test also has no explicit failure path if no error is thrown.

💡 Proposed fix
 test('P2011: NullConstraintViolation has meta.target', async () => {
-  try {
-    await prisma.$executeRaw`INSERT INTO "User" ("email") VALUES (NULL)`
-  } catch (e: any) {
-    if (e.code === 'P2011') {
-      expect(e.meta).toBeDefined()
-      expect(e.meta.target).toBeDefined()
-    }
-  }
+  let caught: any
+  try {
+    await prisma.$executeRaw`INSERT INTO "User" ("email") VALUES (NULL)`
+  } catch (e: any) {
+    caught = e
+  }
+
+  expect(caught).toBeDefined()
+  if (caught.code === 'P2011') {
+    expect(caught.meta).toBeDefined()
+    expect(caught.meta.target).toBeDefined()
+  } else {
+    // Raw query path may map adapter errors to P2010.
+    expect(caught.code).toBe('P2010')
+  }
 })

@Yashsingh045
Copy link
Author

Hey @jacek-prisma ,

Added a functional regression test at packages/client/tests/functional/issues/29344-adapter-constraint-meta/ following the pattern from 29309-datetime-cursor.

The test verifies:

  • P2002 (UniqueConstraintViolation): meta.target is populated
  • P2003 (ForeignKeyConstraintViolation): meta.field_name is populated
  • P2011 (NullConstraintViolation): meta.target is populated (best effort, conditionally checked)

Tests pass locally with js_libsql adapter. CI should cover the remaining adapters (pg, planetscale, etc.).

@jacek-prisma
Copy link
Contributor

Where did the idea for field_name come from? Is that from some previous Prisma version? I'm a bit surprised it's set to err.cause.constraint.index for constraint errors

@codspeed-hq
Copy link

codspeed-hq bot commented Mar 24, 2026

Merging this PR will not alter performance

✅ 17 untouched benchmarks
⏩ 30 skipped benchmarks1


Comparing Yashsingh045:fix/mysql-p2002-meta-target (11a91a0) with main (74839a9)

Open in CodSpeed

Footnotes

  1. 30 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

@Yashsingh045
Copy link
Author

Where did the idea for field_name come from? Is that from some previous Prisma version? I'm a bit surprised it's set to err.cause.constraint.index for constraint errors

hey @jacek-prisma ,

"Regarding the field_name meta property:

  • Origin of field_name: It is indeed the standard meta property for the P2003 (ForeignKeyConstraintViolation) error across Prisma, used to expose the failing foreign key field for programmatic access.
  • Mapping refinement: You're absolutely right about the mapping from index. In my initial implementation for driver adapters, I was incorrectly using the database constraint name (index) as a fallback for field_name when specific column info was missing.

I have now refined the implementation in user-facing-error.ts to:

  • Only populate meta.field_name when actual field/column names are provided by the adapter.
  • Remove the inaccurate fallback that mapped the constraint index to field_name.
  • Update the functional tests to accommodate cases where field_name might be optional or missing if the driver only provides constraint information.

This ensures that the meta object remains accurate and strictly represents database columns, while the constraint name itself still appears correctly in the human-readable error message (handled separately)."

Summary of Final Changes:

  • packages/client-engine-runtime/src/user-facing-error.ts: Removed the incorrect mapping of index to field_name.

  • packages/client/tests/functional/issues/29344-adapter-constraint-meta/tests.ts: Updated assertions to make field_name optional where necessary and fixed a minor indentation linting issue.

@jacek-prisma
Copy link
Contributor

Looks like the tests need to some adjustments for your change, the CI is failing

@Yashsingh045
Copy link
Author

hey @jacek-prisma ,

  • Fixed CI Linting Failures: I added // eslint-disable-next-line import/no-duplicates to the 3 E2E test files (mysql, postgres, sqlite).
  • Why?: These tests are supposed to import the same module multiple times to verify different resolution paths. However, a recent update in the Prisma repo's linting configuration started flagging these as errors. By adding these suppressions, I've cleared the "Lint" failure on CI.

The PR is ready for another Look

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

Successfully merging this pull request may close these issues.

3 participants