From 1a75bdb05810c82695d05311fce4c9973dfd1168 Mon Sep 17 00:00:00 2001 From: calebboyd Date: Wed, 23 Jan 2019 20:21:34 -0600 Subject: [PATCH] fix: avoid syncronous errors in compile method --- index.js | 15 ++++++++++++++- package-lock.json | 33 ++++++++++++++++++++++++++++++++- package.json | 5 +++-- src/compiler.ts | 13 ++++++++++--- src/nexe.ts | 35 ++++++++++++++++------------------- src/options.ts | 4 ++-- src/steps/bundle.ts | 4 ++-- tsconfig.json | 2 +- 8 files changed, 80 insertions(+), 31 deletions(-) diff --git a/index.js b/index.js index cc0e78e..b28edff 100755 --- a/index.js +++ b/index.js @@ -10,7 +10,20 @@ if (require.main === module) { process.stderr.write(showHelp ? options.help : options.version + eol) } else { const nexe = require('./lib/nexe') - nexe.compile(argv).catch(() => { + nexe.compile(argv).catch((error) => { + const NexeError = require('./lib/compiler').NexeError + const chalk = require('chalk') + const isSilent = Boolean(argv.silent === true || argv.loglevel === 'silent') + if (!isSilent) { + if (error instanceof NexeError) { + process.stderr.write(eol + chalk.red('Error: ') + error.message + eol + + eol + 'See nexe -h for usage..' + eol + eol + ) + } else { + process.stderr.write(error.stack + eol) + } + } + process.exit(1) }) } diff --git a/package-lock.json b/package-lock.json index d6b9112..eb6a0b8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "nexe", - "version": "3.0.0-beta.14", + "version": "3.0.0-beta.15", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -42,6 +42,37 @@ "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", "dev": true }, + "@types/decompress": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/@types/decompress/-/decompress-4.2.3.tgz", + "integrity": "sha512-W24e3Ycz1UZPgr1ZEDHlK4XnvOr+CpJH3qNsFeqXwwlW/9END9gxn3oJSsp7gYdiQxrXUHwUUd3xuzVz37MrZQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/download": { + "version": "6.2.4", + "resolved": "https://registry.npmjs.org/@types/download/-/download-6.2.4.tgz", + "integrity": "sha512-Lo5dy3ai6LNnbL663sgdzqL1eib11u1yKH6w3v3IXEOO4kRfQpMn1qWUTaumcHLACjFp1RcBx9tUXEvJoR3vcA==", + "dev": true, + "requires": { + "@types/decompress": "*", + "@types/got": "^8", + "@types/node": "*" + }, + "dependencies": { + "@types/got": { + "version": "8.3.5", + "resolved": "https://registry.npmjs.org/@types/got/-/got-8.3.5.tgz", + "integrity": "sha512-AaXSrIF99SjjtPVNmCmYb388HML+PKEJb/xmj4SbL2ZO0hHuETZZzyDIKfOqaEoAHZEuX4sC+FRFrHYJoIby6A==", + "dev": true, + "requires": { + "@types/node": "*" + } + } + } + }, "@types/events": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", diff --git a/package.json b/package.json index e61d6d7..8f73460 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "nexe", "description": "Create a single executable out of your Node.js application", "license": "MIT", - "version": "3.0.0-beta.14", + "version": "3.0.0-beta.15", "contributors": [ "Craig Condon (http://crcn.io)", "Jared Allard ", @@ -37,9 +37,9 @@ "app-builder": "^5.2.0", "caw": "^2.0.1", "chalk": "^2.4.1", + "cherow": "1.6.8", "download": "^7.1.0", "globby": "^8.0.1", - "cherow": "1.6.8", "got": "^9.5.0", "minimist": "^1.2.0", "mkdirp": "^0.5.1", @@ -51,6 +51,7 @@ }, "devDependencies": { "@types/chai": "^4.1.7", + "@types/download": "^6.2.4", "@types/execa": "^0.9.0", "@types/globby": "^8.0.0", "@types/got": "^9.2.2", diff --git a/src/compiler.ts b/src/compiler.ts index d4ccddd..3a6f9eb 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -35,6 +35,13 @@ export interface NexeFile { export { NexeOptions } +export class NexeError extends Error { + constructor(m: string) { + super(m) + Object.setPrototypeOf(this, NexeError.prototype) + } +} + export class NexeCompiler { /** * Epoch of when compilation started @@ -178,7 +185,7 @@ export class NexeCompiler { assertBuild() { if (!this.options.build) { - throw new Error('This feature is only available with `--build`') + throw new NexeError('This feature is only available with `--build`') } } @@ -211,7 +218,7 @@ export class NexeCompiler { } if (code != 0) { const error = `${command} ${args.join(' ')} exited with code: ${code}` - reject(new Error(error)) + reject(new NexeError(error)) } resolve() }) @@ -255,7 +262,7 @@ export class NexeCompiler { const asset = githubRelease.assets.find(x => x.name === assetName) if (!asset) { - throw new Error(`${assetName} not available, create it using the --build flag`) + throw new NexeError(`${assetName} not available, create it using the --build flag`) } const filename = this.getNodeExecutableLocation(target) diff --git a/src/nexe.ts b/src/nexe.ts index bcc422d..315223f 100644 --- a/src/nexe.ts +++ b/src/nexe.ts @@ -1,6 +1,6 @@ import { EOL } from 'os' import { compose } from 'app-builder' -import { NexeCompiler } from './compiler' +import { NexeCompiler, NexeError } from './compiler' import { normalizeOptions, NexeOptions, NexePatch } from './options' import resource from './steps/resource' import clean from './steps/clean' @@ -15,31 +15,28 @@ async function compile( compilerOptions?: Partial, callback?: (err: Error | null) => void ) { - const options = normalizeOptions(compilerOptions) - const compiler = new NexeCompiler(options) + let error = null, + options: NexeOptions | null = null, + compiler: NexeCompiler | null = null - const nexe = compose( - clean, - resource, - cli, - bundle, - shim, - options.build ? [download, artifacts, ...patches, ...(options.patches as NexePatch[])] : [], - options.plugins as NexePatch[] - ) - - let error = null try { - await nexe(compiler) + options = normalizeOptions(compilerOptions) + compiler = new NexeCompiler(options) + await compose( + clean, + resource, + cli, + bundle, + shim, + options.build ? [download, artifacts, ...patches, ...(options.patches as NexePatch[])] : [], + options.plugins as NexePatch[] + )(compiler) } catch (e) { error = e } if (error) { - compiler.quit(error) - if (compiler.options.loglevel !== 'silent' && error) { - process.stderr.write(EOL + error.message + EOL) - } + compiler && compiler.quit(error) if (callback) return callback(error) return Promise.reject(error) } diff --git a/src/options.ts b/src/options.ts index cd57ac2..b74f82f 100644 --- a/src/options.ts +++ b/src/options.ts @@ -1,5 +1,5 @@ import * as parseArgv from 'minimist' -import { NexeCompiler } from './compiler' +import { NexeCompiler, NexeError } from './compiler' import { isWindows, STDIN_FLAG } from './util' import { basename, extname, join, isAbsolute, resolve } from 'path' import { getTarget, NexeTarget } from './target' @@ -222,7 +222,7 @@ export function resolveEntry( result = resolveFileNameSync(cwd, '.') } if (!result.absPath) { - throw new Error(`Entry file "${input}" not found!`) + throw new NexeError(`Entry file "${input || ''}" not found!`) } return result.absPath } diff --git a/src/steps/bundle.ts b/src/steps/bundle.ts index 6d76f03..e9a8414 100644 --- a/src/steps/bundle.ts +++ b/src/steps/bundle.ts @@ -1,4 +1,4 @@ -import { NexeCompiler } from '../compiler' +import { NexeCompiler, NexeError } from '../compiler' import { resolve, relative } from 'path' import { each } from '@calebboyd/semaphore' import resolveFiles from 'resolve-dependencies' @@ -48,7 +48,7 @@ export default async function bundle(compiler: NexeCompiler, next: any) { if ( warnings.filter(x => x.startsWith('Error parsing file') && !x.includes('node_modules')).length ) { - throw new Error('Parsing Error:\n' + warnings.join('\n')) + throw new NexeError('Parsing Error:\n' + warnings.join('\n')) } await each(Object.keys(files), (filename: string) => compiler.addResource(filename), { diff --git a/tsconfig.json b/tsconfig.json index d75b514..47b6ce5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -3,7 +3,7 @@ "target":"es5", "skipLibCheck": true, "experimentalDecorators": true, - "lib": ["es2017"], + "lib": ["es2018"], "module": "commonjs", "outDir": "./lib", "strict": true