Handle Prisma known request errors without generic Sentry alerts - #1375
Handle Prisma known request errors without generic Sentry alerts#1375cursor[bot] wants to merge 1 commit into
Conversation
Co-authored-by: Neil Raina <makeitraina@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| return ( | ||
| typeof candidate.code === 'string' && | ||
| (candidate.name === PRISMA_KNOWN_REQUEST_ERROR_NAME || constructorName === PRISMA_KNOWN_REQUEST_ERROR_NAME) | ||
| ) |
There was a problem hiding this comment.
Structural guard silent-swallows errors if name matches accidentally
The guard accepts any object with a code: string AND either name === 'PrismaClientKnownRequestError' or constructor.name === 'PrismaClientKnownRequestError'. If any non-Prisma code throws a plain object like { code: 'P2025', name: 'PrismaClientKnownRequestError' }, it will be silently treated as a known Prisma error — returning a 404 and emitting only a console.warn instead of a console.error. The result is a swallowed error that never reaches Sentry. Adding a check for at least one additional Prisma-specific property (e.g. typeof candidate.clientVersion === 'string') would tighten the guard without breaking the structural approach.
| it('recognizes Prisma known request errors across module boundaries', async () => { | ||
| const error = { | ||
| code: 'P2025', | ||
| constructor: { name: 'PrismaClientKnownRequestError' }, | ||
| message: 'Record not found', | ||
| } | ||
| const handler = async (_req: NextRequest, _params: any) => { | ||
| throw error | ||
| } | ||
|
|
||
| const nextResponse = await withErrorHandler(handler)(req, null) | ||
| const response = await nextResponse.json() | ||
| expect(response.error).toBe('The requested resource was not found') | ||
| expect(nextResponse.status).toBe(httpStatus.NOT_FOUND) | ||
| expect(console.error).not.toHaveBeenCalled() | ||
| expect(console.warn).toHaveBeenCalledWith(error) | ||
| }) |
There was a problem hiding this comment.
Cross-module boundary test exercises the wrong code path
The test object { code: 'P2025', constructor: { name: '...' } } has no name property, so it passes isPrismaKnownRequestError via the constructor-as-plain-object branch of getConstructorName. A real cross-module Prisma error is an actual class instance — its this.name is explicitly set to 'PrismaClientKnownRequestError' by Prisma, so it would match the candidate.name check, not the constructorName check. The test validates an edge case that is unlikely to occur in practice (a constructor property that is a plain object rather than a function). A more representative cross-module test would simulate an actual different-module instance where both name and a function constructor are present but instanceof fails.
Changes
instanceofdependency with a structural Prisma known-request error guard so bundled/runtime class mismatches still normalize correctly.P2002unique constraint violations to a 409 Conflict response and treat them as expected client errors instead of generic logged 400s.Testing Criteria
yarn test src/app/api/tests/utils/withErrorHandler.test.ts --runInBand— 11 tests passed, covering existing API/Zod/Copilot/Prisma normalization plus new structural and P2002 cases.yarn prettier:check— passed.yarn lint:check— passed with 0 errors and existing React hook/compiler warnings.yarn tsc— still fails on the repository's pre-existingsrc/icons/index.tsSVG module declaration errors before reaching this change.Notes
Linearreturned 401;Sentryneeds auth), so the Sentry-project gate was inferred from the triage trigger title plus this repo's Sentry config (project: 'tasks').Impact & Surface Area of Change
withErrorHandler.console.errorSentry alerts when the Prisma error class identity differs at runtime.