Skip to content

Commit

Permalink
feat(sdk): improved error reporting by adding detail to getConfig and…
Browse files Browse the repository at this point in the history
… getDmmf error (#13736)

* sdk: improved error reporting by adding detail to getConfig and getDmmf error

* sdk: added openssl fix proposal

* sdk: added comments to errorHelpers

* sdk: updated structured error output in getDmmf

* sdk: updated structured error output in getConfig

* ci: fix tests

* sdk: add tests for loadNodeAPILibrary

* Update packages/sdk/src/engine-commands/getConfig.ts

Co-authored-by: Joël Galeran <Jolg42@users.noreply.github.com>

* Update packages/sdk/src/engine-commands/getConfig.ts

Co-authored-by: Joël Galeran <Jolg42@users.noreply.github.com>

* Update packages/sdk/src/engine-commands/getDmmf.ts

Co-authored-by: Joël Galeran <Jolg42@users.noreply.github.com>

* Update packages/sdk/src/engine-commands/getDmmf.ts

Co-authored-by: Joël Galeran <Jolg42@users.noreply.github.com>

* ci: fix tests for getDmmf

* ci: fix tests

* ci: fix tests

* ci: fix tests

* ci: fix tests

* ci: fix tests

* ci: fixed getConfig tests

* chore: simplified query-engine test assertions

* chore: fix typo

* fix: tests

* internals: updated openssl error message

* Update packages/internals/src/__tests__/engine-commands/queryEngineCommons.test.ts

Co-authored-by: Joël Galeran <Jolg42@users.noreply.github.com>

Co-authored-by: Joël Galeran <Jolg42@users.noreply.github.com>
  • Loading branch information
jkomyno and Jolg42 committed Jun 24, 2022
1 parent 5e4d9c2 commit 8e90f8a
Show file tree
Hide file tree
Showing 22 changed files with 354 additions and 126 deletions.
2 changes: 1 addition & 1 deletion packages/cli/src/Doctor.ts
@@ -1,5 +1,4 @@
import type { DMMF } from '@prisma/generator-helper'
import { getSchemaPathAndPrint } from '@prisma/migrate'
import {
arg,
canConnectToDatabase,
Expand All @@ -14,6 +13,7 @@ import {
loadEnvFile,
pick,
} from '@prisma/internals'
import { getSchemaPathAndPrint } from '@prisma/migrate'
import chalk from 'chalk'
import equal from 'fast-deep-equal'
import fs from 'fs'
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/Format.ts
@@ -1,6 +1,6 @@
import { getSchemaPathAndPrint } from '@prisma/migrate'
import type { Command } from '@prisma/internals'
import { arg, ErrorArea, format, formatms, formatSchema, getDMMF, HelpError, RustPanic } from '@prisma/internals'
import { getSchemaPathAndPrint } from '@prisma/migrate'
import chalk from 'chalk'
import fs from 'fs'
import os from 'os'
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/Generate.ts
@@ -1,5 +1,4 @@
import { enginesVersion } from '@prisma/engines'
import { getSchemaPathAndPrint } from '@prisma/migrate'
import {
arg,
Command,
Expand All @@ -19,6 +18,7 @@ import {
parseEnvValue,
Platform,
} from '@prisma/internals'
import { getSchemaPathAndPrint } from '@prisma/migrate'
import chalk from 'chalk'
import fs from 'fs'
import logUpdate from 'log-update'
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/Studio.ts
@@ -1,6 +1,6 @@
import { enginesVersion } from '@prisma/engines'
import { getSchemaPathAndPrint } from '@prisma/migrate'
import { arg, checkUnsupportedDataProxy, Command, format, HelpError, isError, loadEnvFile } from '@prisma/internals'
import { getSchemaPathAndPrint } from '@prisma/migrate'
import { StudioServer } from '@prisma/studio-server'
import chalk from 'chalk'
import getPort from 'get-port'
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/Validate.ts
@@ -1,6 +1,6 @@
import { getSchemaPathAndPrint } from '@prisma/migrate'
import type { Command } from '@prisma/internals'
import { arg, format, getConfig, getDMMF, HelpError, loadEnvFile } from '@prisma/internals'
import { getSchemaPathAndPrint } from '@prisma/migrate'
import chalk from 'chalk'
import fs from 'fs'

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/__tests__/artificial-panic.test.ts
@@ -1,5 +1,5 @@
import { DbPull } from '@prisma/migrate'
import { isRustPanic, jestConsoleContext, jestContext } from '@prisma/internals'
import { DbPull } from '@prisma/migrate'

import { Format } from '../Format'
import { Validate } from '../Validate'
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/__tests__/commands/CLI.test.ts
@@ -1,3 +1,4 @@
import { handlePanic, jestConsoleContext, jestContext } from '@prisma/internals'
import {
DbCommand,
DbPull,
Expand All @@ -11,7 +12,6 @@ import {
MigrateResolve,
MigrateStatus,
} from '@prisma/migrate'
import { handlePanic, jestConsoleContext, jestContext } from '@prisma/internals'

import { CLI } from '../../CLI'

Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/bin.ts
Expand Up @@ -2,6 +2,7 @@

import Debug from '@prisma/debug'
import { enginesVersion } from '@prisma/engines'
import { arg, handlePanic, HelpError, isCurrentBinInstalledGlobally, isError, isRustPanic } from '@prisma/internals'
import {
DbCommand,
DbExecute,
Expand All @@ -17,7 +18,6 @@ import {
MigrateResolve,
MigrateStatus,
} from '@prisma/migrate'
import { arg, handlePanic, HelpError, isCurrentBinInstalledGlobally, isError, isRustPanic } from '@prisma/internals'
import chalk from 'chalk'
import path from 'path'

Expand Down
4 changes: 3 additions & 1 deletion packages/client/scripts/get-packed-client.js
Expand Up @@ -9,4 +9,6 @@ async function main() {
console.log(`Saving packed client to ${target}`)
}

main()
main().catch((e) => {
throw e
})
6 changes: 4 additions & 2 deletions packages/client/src/__tests__/dmmf.test.ts
@@ -1,3 +1,4 @@
import { serializeQueryEngineName } from '@prisma/internals'
import stripAnsi from 'strip-ansi'

import { getDMMF } from '../generation/getDMMF'
Expand Down Expand Up @@ -347,8 +348,9 @@ describe('dmmf', () => {
try {
await getDMMF({ datamodel })
} catch (e) {
expect(stripAnsi(e.message)).toMatchInlineSnapshot(`
Get DMMF: Schema parsing
expect(serializeQueryEngineName(stripAnsi(e.message))).toMatchInlineSnapshot(`
Get DMMF: Schema parsing - Error while interacting with query-engine-NORMALIZED
Error code: P1012
error: Error validating: You defined the enum \`PostKind\`. But the current connector does not support enums.
--> schema.prisma:14
|
Expand Down
14 changes: 11 additions & 3 deletions packages/client/src/__tests__/generation/generator.test.ts
@@ -1,4 +1,11 @@
import { ClientEngineType, getClientEngineType, getGenerator, getPackedPackage, parseEnvValue } from '@prisma/internals'
import {
ClientEngineType,
getClientEngineType,
getGenerator,
getPackedPackage,
parseEnvValue,
serializeQueryEngineName,
} from '@prisma/internals'
import fs from 'fs'
import path from 'path'
import rimraf from 'rimraf'
Expand Down Expand Up @@ -116,8 +123,9 @@ describe('generator', () => {
skipDownload: true,
})
} catch (e) {
expect(stripAnsi(e.message)).toMatchInlineSnapshot(`
Get DMMF: Schema parsing
expect(serializeQueryEngineName(stripAnsi(e.message))).toMatchInlineSnapshot(`
Get DMMF: Schema parsing - Error while interacting with query-engine-NORMALIZED
Error code: P1012
error: Error validating model "public": The model name \`public\` is invalid. It is a reserved name. Please change it. Read more at https://pris.ly/d/naming-models
--> schema.prisma:10
|
Expand Down
@@ -1,5 +1,5 @@
import { Migrate } from '@prisma/migrate'
import { createDatabase } from '@prisma/internals'
import { Migrate } from '@prisma/migrate'

export type MigrateOptions = {
connectionString: string
Expand Down
15 changes: 11 additions & 4 deletions packages/internals/src/__tests__/engine-commands/getDmmf.test.ts
Expand Up @@ -12,7 +12,11 @@ if (process.env.CI) {
jest.setTimeout(60_000)
}

describe('getDMMF', () => {
const describeIf = (condition: boolean) => (condition ? describe : describe.skip)

describeIf(
process.env.PRISMA_CLI_QUERY_ENGINE_TYPE === 'library' || process.env.PRISMA_CLI_QUERY_ENGINE_TYPE === undefined,
)('getDMMF', () => {
test('simple model, no datasource', async () => {
const dmmf = await getDMMF({
datamodel: `model A {
Expand Down Expand Up @@ -144,7 +148,8 @@ describe('getDMMF', () => {
await getDMMF({ datamodel })
} catch (e) {
expect(stripAnsi(e.message)).toMatchInlineSnapshot(`
"Get DMMF: Schema parsing
"Get DMMF: Schema parsing - Error while interacting with query-engine-node-api library
Error code: P1012
error: Error parsing attribute \\"@default\\": The \`autoincrement()\` default value is used on a non-id field even though the datasource does not support this.
--> schema.prisma:7
|
Expand Down Expand Up @@ -184,7 +189,8 @@ describe('getDMMF', () => {
await getDMMF({ datamodel })
} catch (e) {
expect(stripAnsi(e.message)).toMatchInlineSnapshot(`
"Get DMMF: Schema parsing
"Get DMMF: Schema parsing - Error while interacting with query-engine-node-api library
Error code: P1012
error: Error parsing attribute \\"@default\\": The \`autoincrement()\` default value is used on a non-indexed field even though the datasource does not support this.
--> schema.prisma:7
|
Expand Down Expand Up @@ -340,7 +346,8 @@ describe('getDMMF', () => {
await getDMMF({ datamodel })
} catch (e) {
expect(stripAnsi(e.message)).toMatchInlineSnapshot(`
"Get DMMF: Schema parsing
"Get DMMF: Schema parsing - Error while interacting with query-engine-node-api library
Error code: P1012
error: Field \\"id\\" is already defined on model \\"User\\".
--> schema.prisma:12
|
Expand Down
@@ -0,0 +1,68 @@
import { BinaryType } from '@prisma/fetch-engine'
import * as E from 'fp-ts/Either'

import { loadNodeAPILibrary } from '../../engine-commands/queryEngineCommons'
import { resolveBinary } from '../../resolveBinary'
import * as loadUtils from '../../utils/load'

const describeIf = (condition: boolean) => (condition ? describe : describe.skip)

describeIf(process.env.PRISMA_CLI_QUERY_ENGINE_TYPE !== 'binary')('loadNodeAPILibrary', () => {
it('error path', async () => {
const spyLoadTag = 'error-load'
const spyLoad = jest.spyOn(loadUtils, 'load').mockImplementation((id: string) => {
throw new Error(spyLoadTag)
})

try {
const queryEnginePath = await resolveBinary(BinaryType.libqueryEngine)
const result = await loadNodeAPILibrary(queryEnginePath)()

expect(E.isLeft(result)).toBe(true)

if (E.isLeft(result)) {
expect(result.left.type).toEqual('connection-error')
expect(result.left.reason).toEqual('Unable to establish a connection to query-engine-node-api library.')
expect(result.left.error).toBeTruthy()
}
} finally {
spyLoad.mockRestore()
}
})

it('error path, openssl', async () => {
const spyLoadTag = 'error-load, something something openssl installation'
const spyLoad = jest.spyOn(loadUtils, 'load').mockImplementation((id: string) => {
throw new Error(spyLoadTag)
})

try {
const queryEnginePath = await resolveBinary(BinaryType.libqueryEngine)
const result = await loadNodeAPILibrary(queryEnginePath)()

expect(E.isLeft(result)).toBe(true)

if (E.isLeft(result)) {
expect(result.left.type).toEqual('connection-error')
expect(result.left.reason).toEqual(
`Unable to establish a connection to query-engine-node-api library. It seems there is a problem with your OpenSSL installation!`,
)
expect(result.left.error).toBeTruthy()
}
} finally {
spyLoad.mockRestore()
}
})

it('happy path', async () => {
const queryEnginePath = await resolveBinary(BinaryType.libqueryEngine)
const result = await loadNodeAPILibrary(queryEnginePath)()

expect(E.isRight(result)).toBe(true)

if (E.isRight(result)) {
expect(result.right.NodeAPIQueryEngineLibrary).toBeTruthy()
expect(result.right.NodeAPIQueryEngineLibrary.QueryEngine).toBeTruthy()
}
})
})
3 changes: 3 additions & 0 deletions packages/internals/src/engine-commands/errorHelpers.ts
@@ -1,6 +1,9 @@
import { formatTable } from '../utils/formatTable'
import { version } from '../utils/getVersion'

/**
* Adds `Prisma CLI Version : x.x.x` at the bottom of the error output.
*/
export function addVersionDetailsToErrorMessage(message: string) {
const rows = [['Prisma CLI Version', version]]
return `${message}
Expand Down

0 comments on commit 8e90f8a

Please sign in to comment.