fix(webapp): capture Prisma infra errors and obfuscate leaked messages#3960
fix(webapp): capture Prisma infra errors and obfuscate leaked messages#3960d-cs wants to merge 7 commits into
Conversation
…eir messages Prisma infrastructure failures (P1xxx-class: DB unreachable/timed out/connection dropped, engine init/panic) carry the database hostname in their message. Capture them centrally and ensure they never reach API clients verbatim. - db.server.ts: a $allOperations extension on the writer and replica clients logs infra errors with the model/operation, then rethrows the ORIGINAL error so the ~40 call sites that branch on error.code (and transaction retries) keep working. - transaction boundary: log infra errors that surface from $transaction() without a Prisma code (e.g. PrismaClientInitializationError), which the existing coded- error callback misses. - clientSafeErrorMessage(): swap an infra error's message for "Internal Server Error" at the API routes that returned it raw, leaving status codes, headers, and all non-infra messages unchanged. Applied to the batch trigger routes, schedule delete, and the worker continue action. Adds testcontainer + real-error-instance tests covering message obfuscation, pass-through of P2xxx codes, transaction-interior firing, and the boundary path.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📜 Recent review details⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
🧰 Additional context used📓 Path-based instructions (6)**/*.{ts,tsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
{packages/core,apps/webapp}/**/*.{ts,tsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (.github/copilot-instructions.md)
Files:
**/*.ts📄 CodeRabbit inference engine (.cursor/rules/otel-metrics.mdc)
Files:
apps/webapp/**/*.{ts,tsx}📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)
Files:
**/*.{js,ts,tsx,jsx,css,json,md}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧠 Learnings (8)📚 Learning: 2026-03-22T13:26:12.060ZApplied to files:
📚 Learning: 2026-03-22T19:24:14.403ZApplied to files:
📚 Learning: 2026-05-18T08:21:27.694ZApplied to files:
📚 Learning: 2026-05-18T08:21:27.694ZApplied to files:
📚 Learning: 2026-06-13T19:53:13.759ZApplied to files:
📚 Learning: 2026-05-12T21:04:05.815ZApplied to files:
📚 Learning: 2026-06-04T18:16:35.386ZApplied to files:
📚 Learning: 2026-06-09T17:58:04.699ZApplied to files:
🔇 Additional comments (2)
WalkthroughThree new exported functions are added to 🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
- api.v1.runs.$runParam.replay.ts returned a raw error.message; route it through clientSafeErrorMessage so infra errors are obfuscated like the other patched routes. - Tag an infra error when the client extension logs it at the statement level, and skip it in the $transaction-boundary loggers, so a single failure is logged exactly once instead of twice inside a transaction.
…loads Code review caught that the infraErrorAlreadyLogged guard was added to only the named-$transaction callback; the anonymous overload still double-logged statement-level infra errors. Extract one shared boundary callback so the guard can't drift between the two overloads. Also harden the dedupe marker: define it non-enumerable (so error-spreads can't copy the tag onto a different error) and best-effort (so a frozen error object can't make the assignment throw and mask the original error).
@trigger.dev/build
trigger.dev
@trigger.dev/core
@trigger.dev/python
@trigger.dev/react-hooks
@trigger.dev/redis-worker
@trigger.dev/rsc
@trigger.dev/schema-to-json
@trigger.dev/sdk
commit: |
Summary
Prisma infrastructure failures (P1xxx-class: database unreachable, timed out, connection dropped, engine init/panic) carry the database hostname in their
.message. This captures them centrally for observability and ensures they never reach API clients verbatim.Design
A
$allOperationsclient extension on the writer and replica clients logs infrastructure errors with the originating model and operation, then rethrows the original error unchanged — call sites that branch onerror.code(unique-violation idempotency, not-found handling) and transaction retries keep working. Only infrastructure errors are logged; routine query/validation errors (P2xxx) are left alone.$allOperationscan't see the transaction boundary ($transactionis a client method, not an operation), so infrastructure errors surfacing from$transaction()without a Prisma code — e.g.PrismaClientInitializationError— are logged separately at the transaction wrapper, where the existing coded-error path would otherwise miss them.clientSafeErrorMessage()swaps an infrastructure error's message for"Internal Server Error"at the API routes that previously returnederror.messageraw. Status codes, headers, and every non-infrastructure message are unchanged.Test plan
$transactionkeep their code (retry logic intact)clientSafeErrorMessageobfuscates infra messages, preserves all otherspnpm run typecheck --filter webapp(12/12)Note
Overlaps with #3391 (Prisma 7 migration) on
apps/webapp/app/db.server.ts— coordinate rebasing.