-
Notifications
You must be signed in to change notification settings - Fork 2k
fix(adapter-pg): validate database connection during connect #28925
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
base: main
Are you sure you want to change the base?
Conversation
WalkthroughAdds a connection validation step to PrismaPgAdapterFactory by running Changes
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro 📒 Files selected for processing (1)
🧰 Additional context used📓 Path-based instructions (1)**/*.{ts,tsx,js,jsx}📄 CodeRabbit inference engine (AGENTS.md)
Files:
🧬 Code graph analysis (1)packages/adapter-pg/src/pg.ts (2)
🔇 Additional comments (3)
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
packages/adapter-pg/src/__tests__/pg.test.ts(6 hunks)packages/adapter-pg/src/pg.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Use kebab-case for new file names (e.g.,query-utils.ts,filter-operators.test.ts)
Avoid creating barrel files (index.tsthat re-export from other modules). Import directly from the source file (e.g.,import { foo } from './utils/query-utils'notimport { foo } from './utils'), unless./utils/index.tsfile already exists
Files:
packages/adapter-pg/src/__tests__/pg.test.tspackages/adapter-pg/src/pg.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Test files named
*.test.tsare excluded from build output via esbuild config; place tests alongside source files
Files:
packages/adapter-pg/src/__tests__/pg.test.ts
🔇 Additional comments (2)
packages/adapter-pg/src/pg.ts (1)
281-303: LGTM! Connection validation ensures early failure detection.The addition of
validateConnection(client)before setting up error handlers correctly addresses the lazy connection issue withpg.Pool. This ensures connection errors surface during$connect()rather than on first query.packages/adapter-pg/src/__tests__/pg.test.ts (1)
113-127: LGTM! Good regression test for unreachable database.Excellent use of the TEST-NET-1 reserved IP address (192.0.2.1) which is guaranteed to be unreachable, and short timeout for fast test execution. This correctly validates the fix for issue #28896.
…nd error handling - Add explicit type guard for TEST_POSTGRES_URI instead of type assertion - Use try-finally to ensure test resource cleanup - Wrap validation errors in DriverAdapterError for consistenc
a831973 to
1ae866e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
📜 Review details
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (2)
packages/adapter-pg/src/__tests__/pg.test.ts(6 hunks)packages/adapter-pg/src/pg.ts(2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
**/*.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,js,jsx}: Use kebab-case for new file names (e.g.,query-utils.ts,filter-operators.test.ts)
Avoid creating barrel files (index.tsthat re-export from other modules). Import directly from the source file (e.g.,import { foo } from './utils/query-utils'notimport { foo } from './utils'), unless./utils/index.tsfile already exists
Files:
packages/adapter-pg/src/__tests__/pg.test.tspackages/adapter-pg/src/pg.ts
**/*.test.{ts,tsx,js,jsx}
📄 CodeRabbit inference engine (AGENTS.md)
Test files named
*.test.tsare excluded from build output via esbuild config; place tests alongside source files
Files:
packages/adapter-pg/src/__tests__/pg.test.ts
🧬 Code graph analysis (2)
packages/adapter-pg/src/__tests__/pg.test.ts (1)
packages/adapter-pg/src/pg.ts (1)
PrismaPgAdapterFactory(262-329)
packages/adapter-pg/src/pg.ts (2)
packages/driver-adapter-utils/src/error.ts (1)
DriverAdapterError(3-11)packages/adapter-pg/src/errors.ts (1)
convertDriverError(37-58)
🔇 Additional comments (4)
packages/adapter-pg/src/pg.ts (1)
317-328: LGTM!The validation logic correctly executes a simple query to verify connectivity and properly wraps errors using
DriverAdapterError(convertDriverError(e)), maintaining consistency with error handling elsewhere in the adapter.packages/adapter-pg/src/__tests__/pg.test.ts (3)
7-23: LGTM!The helper function properly validates the environment variable and provides a clear error message when missing. Centralizing test configuration in
testConfigimproves maintainability.
132-151: LGTM!The test correctly simulates connection failure with an external pool and ensures cleanup via the
finallyblock, even if the assertion fails.
116-130: Verify pool cleanup when factory.connect() fails during validation.When
PrismaPgAdapterFactory.connect()throws an error after creating apg.Pool(e.g., during connection timeout before validation succeeds), ensure the pool is properly cleaned up. While the timeout prevents actual database connections from being established, the pool object still exists and requirespool.end()to shut down internal timers. Verify that either:
- The factory handles pool cleanup on connection failure, or
- The test teardown properly cleans up the factory instance
Orphaned pools in repeated test runs can accumulate even without actual database connections.
Summary
Fixes #28896
This PR fixes issue #28896 where
$connect()succeeds even when PostgreSQL is stopped when using@prisma/adapter-pg. The root cause was thatpg.Pooluses lazy connection initialization, so creating a pool doesn't actually establish a database connection until the first query is executed.Problem
Before this fix:
Expected behavior:
Root Cause
The
PrismaPgAdapterFactory.connect()method only instantiatednew pg.Pool(config)without validating the connection. Sincepg.Pooluses lazy connection initialization, no actual connection attempt occurred until the first query execution, causing$connect()to succeed even when the database was offline.Solution
Added a
validateConnection()private method that executesSELECT 1during theconnect()phase to validate the database is reachable:This method is called in
connect()before returning the adapter, ensuring that any connection errors are surfaced immediately during$connect()rather than being deferred to the first query.Changes Made
packages/adapter-pg/src/pg.ts:validateConnection()private method (lines 318-329)validateConnection()inconnect()before returning adapter (line 284)packages/adapter-pg/src/__tests__/pg.test.ts:getTestConfig()helper to parse PostgreSQL connection URI from environmentTesting
Regression Tests:
Test Requirements:
postgres://prisma:prisma@localhost:5432/tests)Behavior Changes
After this fix:
This is the correct behavior and matches user expectations for connection validation.
Related Work
@prisma/adapter-mariadbwhich usesSELECT VERSION()for capability detection@prisma/adapter-neonhas similar connection error handling testsBreaking Changes
None. This is a bug fix that makes the behavior match documented expectations.
Additional Notes
The ECONNREFUSED error when Docker PostgreSQL is not running is expected and acceptable behavior - it confirms that the connection validation is working correctly and surfacing errors immediately during
$connect()as intended.Summary by CodeRabbit
New Features
Tests
✏️ Tip: You can customize this high-level summary in your review settings.