Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .server-changes/webapp-sentry-fingerprint-p1001.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
area: webapp
type: improvement
---

Group Prisma P1001 ("Can't reach database server") errors into a single Sentry issue via a `beforeSend` fingerprint rule, so DB outages no longer fan out into hundreds of distinct issues that bury other alerts. Adds a small extensible rule table for future collapsing rules.
33 changes: 33 additions & 0 deletions apps/webapp/sentry.server.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
import * as Sentry from "@sentry/remix";
import { addOtelTraceContextToEvent } from "./app/utils/sentryTraceContext.server";

// Rules for collapsing high-volume errors into a single Sentry issue.
// Without this, e.g. a DB outage produces hundreds of distinct issues —
// one per stack trace — which buries other alerts. Add a new rule here
// when you spot another error that fans out across call sites. Keep
// predicates cheap (string compare, not regex over stack traces).
const FINGERPRINT_RULES: Array<{
match: (err: { code?: unknown; errorCode?: unknown; name?: unknown }) => boolean;
fingerprint: string;
tags?: Record<string, string>;
}> = [
{
// Prisma surfaces P1001 on `code` for KnownRequestError (mid-query connection drop)
// and `errorCode` for InitializationError (client failed to connect at startup).
match: (err) => err.code === "P1001" || err.errorCode === "P1001",
fingerprint: "prisma-p1001-db-unreachable",
tags: { db_unreachable: "true" },
},
];
Comment on lines +4 to +21
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check Prisma source code for P1001 error property names

# Search for P1001 error definitions and usage in node_modules
echo "=== Searching for P1001 in Prisma client ==="
fd -e d -d 1 'prisma' node_modules/@prisma 2>/dev/null | head -1 | xargs -I {} find {} -name "*.d.ts" -o -name "*.ts" 2>/dev/null | xargs rg -n "P1001|errorCode|KnownRequestError|InitializationError" -C 2 2>/dev/null | head -100

echo ""
echo "=== Checking internal-packages/database for Prisma usage ==="
rg -n "code.*P1001|errorCode.*P1001" internal-packages/database -C 2 | head -50

Repository: triggerdotdev/trigger.dev

Length of output: 8678


🌐 Web query:

Prisma 6.14.0 error code P1001 KnownRequestError InitializationError code vs errorCode property

💡 Result:

In Prisma, P1001 is a specific error code indicating that the Prisma Client cannot reach the database server [1][2]. This error is typically categorized as a PrismaClientInitializationError, which occurs when the query engine fails to start or establish a connection to the database [3][2]. Regarding the distinction between errorCode and code properties: 1. PrismaClientKnownRequestError uses the.code property to identify specific database-related errors (e.g., P2002 for unique constraint violations) [3][2]. 2. PrismaClientInitializationError is documented to use the.errorCode property to identify initialization-related errors, such as P1001 [4][2]. However, there is a known, long-standing issue where the errorCode property on PrismaClientInitializationError can intermittently return undefined [5][6][7]. This often happens when the error is thrown during an implicit connection attempt (e.g., the first query execution) rather than an explicit call to prisma.$connect [6]. Because of this inconsistency, developers are often advised to rely on the error message or to ensure explicit connection handling to improve reliability [6][7]. Regarding Prisma 6.14.0 specifically, users have reported regressions in this version, including breaking changes related to extending the PrismaClient class and issues with the engine connection state [8][9]. If you are encountering unexpected behavior with error handling in this version, it may be related to these broader architectural changes rather than a change in the error property definitions themselves [8].

Citations:


P1001 is a PrismaClientInitializationError, not KnownRequestError—the error detection logic is partially incorrect.

The rule checks err.code === "P1001" || err.errorCode === "P1001", but P1001 only appears on PrismaClientInitializationError via the .errorCode property. The .code property is used only by PrismaClientKnownRequestError for database errors (e.g., P2002). The check for err.code === "P1001" will never match.

Additionally, there is a known Prisma issue where .errorCode on InitializationError can intermittently return undefined during implicit connection attempts (e.g., on the first query execution). Relying solely on the .errorCode check may miss some P1001 errors. Consider either explicitly catching PrismaClientInitializationError by type or handling the error message as a fallback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@apps/webapp/sentry.server.ts` around lines 4 - 21, The FINGERPRINT_RULES
match predicate incorrectly checks err.code for P1001 (which never appears) and
may miss P1001 when err.errorCode is undefined; update the match logic in the
FINGERPRINT_RULES entry so it detects PrismaClientInitializationError
correctly—preferably by checking the error type/name (e.g., instanceof or
err.name === "PrismaClientInitializationError") and err.errorCode === "P1001",
and add a safe fallback that inspects err.message or another cheap string check
for "P1001" to cover cases where errorCode is intermittently undefined.


if (process.env.SENTRY_DSN) {
console.log("🔭 Initializing Sentry");

Expand Down Expand Up @@ -29,6 +48,20 @@ if (process.env.SENTRY_DSN) {
// and stay visible.
ignoreErrors: ["queryRoute() call aborted", /^ServiceValidationError(?::|$)/],
includeLocalVariables: false,

beforeSend(event, hint) {
const err = hint.originalException as
| { code?: unknown; errorCode?: unknown; name?: unknown }
| undefined;
if (!err) return event;

const rule = FINGERPRINT_RULES.find((r) => r.match(err));
if (!rule) return event;

event.fingerprint = [rule.fingerprint];
if (rule.tags) event.tags = { ...event.tags, ...rule.tags };
return event;
},
});

Sentry.addEventProcessor(addOtelTraceContextToEvent);
Expand Down