Skip to content

Commit

Permalink
fix(client): pass thru init error code on binary start (#13551)
Browse files Browse the repository at this point in the history
* replication: add test to assert the error

* refactor: better assertions for error name and code

* refactor: combine skipDBSetup and teardown into one

* fix: pass thru error code
  • Loading branch information
danstarns committed Jun 8, 2022
1 parent 9e74f4a commit b6a0498
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 9 deletions.
7 changes: 5 additions & 2 deletions packages/client/tests/functional/_utils/defineMatrix.ts
@@ -1,7 +1,7 @@
import { U } from 'ts-toolbelt'

import { TestSuiteMatrix } from './getTestSuiteInfo'
import { setupTestSuiteMatrix, TestSuiteMeta } from './setupTestSuiteMatrix'
import { MatrixOptions, setupTestSuiteMatrix, TestSuiteMeta } from './setupTestSuiteMatrix'

type MergedMatrixParams<MatrixT extends TestSuiteMatrix> = U.IntersectOf<MatrixT[number][number]>

Expand All @@ -15,7 +15,10 @@ export interface MatrixTestHelper<MatrixT extends TestSuiteMatrix> {
* @param tests tests factory function. Receives all matrix parameters, used for this suite as a moment
* and generic suite metadata as an arguments
*/
setupTestSuite(tests: (suiteConfig: MergedMatrixParams<MatrixT>, suiteMeta: TestSuiteMeta) => void): void
setupTestSuite(
tests: (suiteConfig: MergedMatrixParams<MatrixT>, suiteMeta: TestSuiteMeta) => void,
options?: MatrixOptions,
): void

/**
* Function for defining test schema. Must be used in your `prisma/_schema.ts`. Return value
Expand Down
14 changes: 12 additions & 2 deletions packages/client/tests/functional/_utils/setupTestSuiteClient.ts
Expand Up @@ -20,7 +20,15 @@ import type { TestSuiteMeta } from './setupTestSuiteMatrix'
* @param suiteConfig
* @returns loaded client module
*/
export async function setupTestSuiteClient(suiteMeta: TestSuiteMeta, suiteConfig: TestSuiteConfig) {
export async function setupTestSuiteClient({
suiteMeta,
suiteConfig,
skipDb,
}: {
suiteMeta: TestSuiteMeta
suiteConfig: TestSuiteConfig
skipDb?: boolean
}) {
const suiteFolderPath = getTestSuiteFolderPath(suiteMeta, suiteConfig)
const previewFeatures = getTestSuitePreviewFeatures(suiteConfig)
const schema = await getTestSuiteSchema(suiteMeta, suiteConfig)
Expand All @@ -31,7 +39,9 @@ export async function setupTestSuiteClient(suiteMeta: TestSuiteMeta, suiteConfig
await setupQueryEngine(getClientEngineType(generator!), await getPlatform())
await setupTestSuiteFiles(suiteMeta, suiteConfig)
await setupTestSuiteSchema(suiteMeta, suiteConfig, schema)
await setupTestSuiteDatabase(suiteMeta, suiteConfig)
if (!skipDb) {
await setupTestSuiteDatabase(suiteMeta, suiteConfig)
}

await generateClient({
datamodel: schema,
Expand Down
22 changes: 18 additions & 4 deletions packages/client/tests/functional/_utils/setupTestSuiteMatrix.ts
Expand Up @@ -4,6 +4,10 @@ import { dropTestSuiteDatabase, setupTestSuiteDbURI } from './setupTestSuiteEnv'

export type TestSuiteMeta = ReturnType<typeof getTestSuiteMeta>

export type MatrixOptions = {
skipDb?: boolean
}

/**
* How does this work from a high level? What steps?
* 1. You create a file that uses `setupTestSuiteMatrix`
Expand Down Expand Up @@ -35,7 +39,10 @@ export type TestSuiteMeta = ReturnType<typeof getTestSuiteMeta>
*
* @param tests where you write your tests
*/
function setupTestSuiteMatrix(tests: (suiteConfig: TestSuiteConfig, suiteMeta: TestSuiteMeta) => void) {
function setupTestSuiteMatrix(
tests: (suiteConfig: TestSuiteConfig, suiteMeta: TestSuiteMeta) => void,
options?: MatrixOptions,
) {
const originalEnv = process.env
const suiteMeta = getTestSuiteMeta()
const suiteTable = getTestSuiteTable(suiteMeta)
Expand All @@ -52,14 +59,21 @@ function setupTestSuiteMatrix(tests: (suiteConfig: TestSuiteConfig, suiteMeta: T
describe(suiteName, () => {
// we inject modified env vars, and make the client available as globals
beforeAll(() => (process.env = { ...setupTestSuiteDbURI(suiteConfig), ...originalEnv }))
beforeAll(async () => (globalThis['loaded'] = await setupTestSuiteClient(suiteMeta, suiteConfig)))
beforeAll(
async () =>
(globalThis['loaded'] = await setupTestSuiteClient({
suiteMeta,
suiteConfig,
skipDb: options?.skipDb,
})),
)
beforeAll(async () => (globalThis['prisma'] = new (await global['loaded'])['PrismaClient']()))
beforeAll(async () => (globalThis['PrismaClient'] = (await global['loaded'])['PrismaClient']))
beforeAll(async () => (globalThis['Prisma'] = (await global['loaded'])['Prisma']))

// we disconnect and drop the database, clean up the env, and global vars
afterAll(async () => await globalThis['prisma']?.$disconnect())
afterAll(async () => await dropTestSuiteDatabase(suiteMeta, suiteConfig))
afterAll(async () => !options?.skipDb && (await globalThis['prisma']?.$disconnect()))
afterAll(async () => !options?.skipDb && (await dropTestSuiteDatabase(suiteMeta, suiteConfig)))
afterAll(() => (process.env = originalEnv))
afterAll(() => delete globalThis['loaded'])
afterAll(() => delete globalThis['prisma'])
Expand Down
10 changes: 10 additions & 0 deletions packages/client/tests/functional/init-error/_matrix.ts
@@ -0,0 +1,10 @@
import { defineMatrix } from '../_utils/defineMatrix'

export default defineMatrix(() => [
[
{
provider: 'postgresql',
url: 'postgresql://invalid:invalid@invalid.org:123/invalid',
},
],
])
19 changes: 19 additions & 0 deletions packages/client/tests/functional/init-error/prisma/_schema.ts
@@ -0,0 +1,19 @@
import { idForProvider } from '../../_utils/idForProvider'
import testMatrix from '../_matrix'

export default testMatrix.setupSchema(({ provider, url }) => {
return /* Prisma */ `
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "${provider}"
url = "${url}"
}
model User {
id ${idForProvider(provider)}
}
`
})
25 changes: 25 additions & 0 deletions packages/client/tests/functional/init-error/tests.ts
@@ -0,0 +1,25 @@
import { PrismaClientInitializationError } from '@prisma/engine-core'

import testMatrix from './_matrix'

// @ts-ignore this is just for type checks
declare let prisma: import('@prisma/client').PrismaClient

testMatrix.setupTestSuite(
() => {
test('should assert that the error has the correct errorCode', async () => {
expect.assertions(2)

try {
await prisma.$connect()
} catch (error) {
const e = error as PrismaClientInitializationError
expect(e.constructor.name).toEqual('PrismaClientInitializationError')
expect(e.errorCode).toEqual('P1001')
} finally {
prisma.$disconnect().catch(() => {})
}
})
},
{ skipDb: true }, // So we can maually call connect for this test
)
2 changes: 1 addition & 1 deletion packages/engine-core/src/binary/BinaryEngine.ts
Expand Up @@ -573,7 +573,7 @@ ${chalk.dim("In case we're mistaken, please report this to us 🙏.")}`)
debug(json)
this.setError(json)
if (this.engineStartDeferred) {
const err = new PrismaClientInitializationError(json.message, this.clientVersion!)
const err = new PrismaClientInitializationError(json.message, this.clientVersion!, json.error_code)
this.engineStartDeferred.reject(err)
}
}
Expand Down

0 comments on commit b6a0498

Please sign in to comment.