Skip to content

Commit

Permalink
improve error handling for invalid chmod
Browse files Browse the repository at this point in the history
  • Loading branch information
timsuchanek committed Oct 7, 2019
1 parent 98b166d commit d21ee9a
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 14 deletions.
1 change: 1 addition & 0 deletions cli/generator-helper/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"repository": "git@github.com:prisma/prisma2.git",
"author": "Tim Suchanek <suchanek@prisma.io>",
"dependencies": {
"chalk": "^2.4.2",
"debug": "^4.1.1"
},
"scripts": {
Expand Down
44 changes: 32 additions & 12 deletions cli/generator-helper/src/GeneratorProcess.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,22 @@
import { ChildProcessByStdio, spawn } from 'child_process'
import byline from './byline'
import { GeneratorManifest, GeneratorOptions, JsonRPC } from './types'
import fs from 'fs'
import chalk from 'chalk'

let globalMessageId = 1

export class GeneratorProcess {
child: ChildProcessByStdio<any, any, any>
child?: ChildProcessByStdio<any, any, any>
listeners: { [key: string]: (result: any, err?: Error) => void } = {}
private exitCode: number | null = null
private stderrLogs: string = ''
private initPromise?: Promise<void>
private initialized: boolean = false
constructor(private executablePath: string) {
this.child = spawn(executablePath, {
stdio: ['pipe', 'inherit', 'pipe'],
})

this.child.on('exit', code => {
this.exitCode = code
})
if (!fs.existsSync(executablePath)) {
throw new Error(`Can't find executable ${executablePath}`)
}
}
async init() {
if (!this.initPromise) {
Expand All @@ -28,7 +26,29 @@ export class GeneratorProcess {
}
initSingleton(): Promise<void> {
return new Promise((resolve, reject) => {
byline(this.child.stderr).on('data', line => {
this.child = spawn(this.executablePath, {
stdio: ['pipe', 'inherit', 'pipe'],
})

this.child.on('exit', code => {
this.exitCode = code
})

this.child.on('error', err => {
if (err.message.includes('EACCES')) {
reject(
new Error(
`The executable at ${
this.executablePath
} lacks the right chmod. Please use ${chalk.bold(
`chmod +x ${this.executablePath}`,
)}`,
),
)
}
})

byline(this.child!.stderr).on('data', line => {
const response = String(line)
this.stderrLogs += response + '\n'
let data
Expand Down Expand Up @@ -84,14 +104,14 @@ export class GeneratorProcess {
this.listeners[messageId] = cb
}
private sendMessage(message: JsonRPC.Request) {
this.child.stdin.write(JSON.stringify(message) + '\n')
this.child!.stdin.write(JSON.stringify(message) + '\n')
}
private getMessageId() {
return globalMessageId++
}
stop() {
if (!this.child.killed) {
this.child.kill()
if (!this.child!.killed) {
this.child!.kill()
}
}
getManifest(): Promise<GeneratorManifest | null> {
Expand Down
10 changes: 8 additions & 2 deletions cli/generator-helper/src/__tests__/generatorHandler.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ const stubOptions: GeneratorOptions = {
}

describe('generatorHandler', () => {
test('not executable', async () => {
const generator = new GeneratorProcess(
path.join(__dirname, 'not-executable'),
)
expect(generator.init()).rejects.toThrow('lacks the right chmod')
})
test('parsing error', async () => {
const generator = new GeneratorProcess(
path.join(__dirname, 'invalid-executable'),
Expand Down Expand Up @@ -68,8 +74,8 @@ describe('generatorHandler', () => {
path.join(__dirname, 'failing-executable'),
)
await generator.init()
expect(generator.getManifest()).rejects.toMatchInlineSnapshot()
expect(generator.generate(stubOptions)).rejects.toMatchInlineSnapshot()
expect(generator.getManifest()).rejects.toThrow()
expect(generator.generate(stubOptions)).rejects.toThrow()
generator.stop()
})
})

0 comments on commit d21ee9a

Please sign in to comment.