From 1e64a1ada60545adf8e7c99fbd1f8766cf2416f9 Mon Sep 17 00:00:00 2001 From: Lars Mikkelsen Date: Wed, 8 Nov 2023 10:42:02 -0500 Subject: [PATCH] revert: use native ES2022 error cause (#5060) This reverts commit 0c4cd0f47e00b43e8c0ce4eef072351a846b566c. --- packages/@ionic/cli-framework/src/errors.ts | 17 ++++++++++++++++- packages/@ionic/cli/src/index.ts | 7 +++++-- packages/@ionic/cli/src/lib/project/index.ts | 6 +++--- packages/@ionic/utils-subprocess/src/index.ts | 14 ++++++++++++-- tsconfig.base.json | 3 +-- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/packages/@ionic/cli-framework/src/errors.ts b/packages/@ionic/cli-framework/src/errors.ts index 262cc26038..375f3b0b12 100644 --- a/packages/@ionic/cli-framework/src/errors.ts +++ b/packages/@ionic/cli-framework/src/errors.ts @@ -1,3 +1,4 @@ +import * as lodash from 'lodash'; import * as util from 'util'; import { ValidationError } from './definitions'; @@ -9,11 +10,25 @@ export const ERROR_IPC_UNKNOWN_PROCEDURE = 'ERR_ICF_IPC_UNKNOWN_PROCEDURE'; export abstract class BaseError extends Error { abstract readonly name: string; + message: string; + stack: string; code?: string; + error?: Error; exitCode?: number; + constructor(message: string) { + super(message); + this.message = message; + this.stack = (new Error()).stack || ''; + } + toString(): string { - return util.inspect(this); + const repr = lodash.pick(this, lodash.pull(lodash.keys(this), 'error')); + + return ( + `${this.name}: ${this.message} ${util.inspect(repr, { breakLength: Infinity })} ${this.stack} ` + + `${this.error ? `\nWrapped: ${this.error.stack ? this.error.stack : this.error}` : ''}` + ); } inspect(): string { diff --git a/packages/@ionic/cli/src/index.ts b/packages/@ionic/cli/src/index.ts index 9b72945baf..fd9be4481a 100644 --- a/packages/@ionic/cli/src/index.ts +++ b/packages/@ionic/cli/src/index.ts @@ -3,7 +3,6 @@ import { readPackageJsonFile } from '@ionic/cli-framework/utils/node'; import { processExit } from '@ionic/utils-process'; import * as Debug from 'debug'; import * as path from 'path'; -import * as util from 'util'; import { IonicNamespace } from './commands'; import { IPCMessage, IonicContext, IonicEnvironment } from './definitions'; @@ -172,7 +171,11 @@ export async function run(pargv: string[]): Promise { } else if (err instanceof BaseError) { ienv.log.error(err.message); } else { - ienv.log.rawmsg(failure(util.inspect(err))); + ienv.log.msg(failure(String(err.stack ? err.stack : err))); + + if (err.stack) { + debug(failure(String(err.stack))); + } } } } diff --git a/packages/@ionic/cli/src/lib/project/index.ts b/packages/@ionic/cli/src/lib/project/index.ts index 77449ca6dd..6a1bfa7d62 100644 --- a/packages/@ionic/cli/src/lib/project/index.ts +++ b/packages/@ionic/cli/src/lib/project/index.ts @@ -55,9 +55,9 @@ export class ProjectDetailsError extends BaseException { /** * The underlying error that caused this error. */ - cause?: Error + readonly error?: Error ) { - super(msg, { cause }); + super(msg); } } @@ -193,7 +193,7 @@ export class ProjectDetails { if (e1) { log.error( `Error while loading config (project config: ${strong(prettyPath(result.configPath))})\n` + - `${e1.cause ? `${e1.message}: ${failure(e1.cause.toString())}` : failure(e1.message)}. ` + + `${e1.error ? `${e1.message}: ${failure(e1.error.toString())}` : failure(e1.message)}. ` + `Run ${input('ionic init')} to re-initialize your Ionic project. Without a valid project config, the CLI will not have project context.` ); diff --git a/packages/@ionic/utils-subprocess/src/index.ts b/packages/@ionic/utils-subprocess/src/index.ts index 0ff8bb63bb..360762d533 100644 --- a/packages/@ionic/utils-subprocess/src/index.ts +++ b/packages/@ionic/utils-subprocess/src/index.ts @@ -35,11 +35,20 @@ export function convertPATH(path = process.env.PATH || ''): string { export class SubprocessError extends Error { readonly name = 'SubprocessError'; + message: string; + stack: string; code?: typeof ERROR_COMMAND_NOT_FOUND | typeof ERROR_NON_ZERO_EXIT | typeof ERROR_SIGNAL_EXIT; + error?: Error; output?: string; signal?: string; exitCode?: number; + + constructor(message: string) { + super(message); + this.message = message; + this.stack = (new Error()).stack || ''; + } } export interface SubprocessOptions extends SpawnOptions {} @@ -163,12 +172,13 @@ export class Subprocess { let err: SubprocessError; if (error.code === 'ENOENT') { - err = new SubprocessError('Command not found.', { cause: error }); + err = new SubprocessError('Command not found.'); err.code = ERROR_COMMAND_NOT_FOUND; } else { - err = new SubprocessError('Command error.', { cause: error }); + err = new SubprocessError('Command error.'); } + err.error = error; reject(err); }); diff --git a/tsconfig.base.json b/tsconfig.base.json index 282786c623..eb7ce3b6e2 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -12,8 +12,7 @@ "target": "ES2021", "types": [], "lib": [ - "ES2021", - "ES2022.Error" + "ES2021" ] } }