diff --git a/package.json b/package.json index d0e7a4ad1..0db21ffa7 100644 --- a/package.json +++ b/package.json @@ -15,6 +15,7 @@ "cac": "^6.7.14", "esbuild": "^0.16.10", "eslint": "^8.30.0", + "tinyspy": "^1.0.2", "tsx": "^3.12.1", "typescript": "^4.9.4" } diff --git a/src/cli.ts b/src/cli.ts index 52fa2affa..03e75a72a 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -6,6 +6,7 @@ import install from './install' import link from './link' import uninstall from './uninstall' import update from './update' +import { wrapCommandAndRemoveStack } from './utils' const cli = cac('jspm') @@ -25,32 +26,32 @@ cli cli .command('install [...packages]', 'install packages') .option('-o, --output ', '.json or .importmap file for the output import-map') - .action(install) + .action(wrapCommandAndRemoveStack(install)) cli .command('update [...packages]', 'update packages') .option('-o, --output ', '.json or .importmap file for the output import-map') - .action(update) + .action(wrapCommandAndRemoveStack(update)) cli .command('uninstall [...packages]', 'remove packages') .option('-o, --output ', '.json or .importmap file for the output import-map') - .action(uninstall) + .action(wrapCommandAndRemoveStack(uninstall)) cli .command('link [...modules]', 'trace install modules') .option('-o, --output ', '.json or .importmap file for the output import-map') - .action(link) + .action(wrapCommandAndRemoveStack(link)) cli .command('inject [...packages]', 'inject the import map into the provided HTML source') .option('-o, --output ', '.html file for the output html with the import-map') - .action(inject) + .action(wrapCommandAndRemoveStack(inject)) cli .command('extract [...packages]', 'extract packages from the import map') .option('-o, --output ', '.json or .importmap file for the output import-map') - .action(extract) + .action(wrapCommandAndRemoveStack(extract)) cli .command('') diff --git a/src/utils.ts b/src/utils.ts index 047503871..41e1fa248 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -10,6 +10,23 @@ export class JspmError extends Error { jspmError = true } +export function wrapCommandAndRemoveStack(fn: Function) { + return async (...args: any[]) => { + try { + await fn(...args) + } + catch (e) { + stopLoading() + process.exitCode = 1 + if (e instanceof JspmError || e?.jspmError) { + console.error(`ERR: ${e.message}`) + return + } + throw e + } + } +} + export async function writeMap( map: IImportMapFile, flags: Flags, diff --git a/test/utils.test.ts b/test/utils.test.ts new file mode 100644 index 000000000..25102f6bc --- /dev/null +++ b/test/utils.test.ts @@ -0,0 +1,20 @@ +import assert from 'assert' +import { spyOn } from 'tinyspy' +import install from '../src/install' +import { wrapCommandAndRemoveStack } from '../src/utils' + +{ + let errorStr = '' + spyOn(console, 'error', (err) => { + errorStr = err + }) + /* basic install 404 with wrapCommandAndRemoveStack should not throw with stack mesage */ + await wrapCommandAndRemoveStack(install)(['package-does-not-exist'], { + env: 'development', + stdout: true, + map: 'test/importmap.json', + }) + assert.ok(process.exitCode === 1) + assert.ok(errorStr.includes('Unable to resolve npm:package-does-not-exist@ to a valid version imported from')) + process.exitCode = 0 +}