From 98b3e775a679f1ffa88ae57c76a5c69d4315a1a7 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Fri, 6 Dec 2024 17:23:55 +0300 Subject: [PATCH 1/3] feat: provide error utils --- package.json | 6 ++ src/main/ts/error.ts | 209 ++++++++++++++++++++++++++++++++++++++++++ src/main/ts/spawn.ts | 24 +++-- src/main/ts/zurk.ts | 1 + target/cjs/spawn.cjs | 6 +- target/cjs/zurk.cjs | 3 + target/dts/error.d.ts | 161 ++++++++++++++++++++++++++++++++ target/dts/spawn.d.ts | 2 + target/esm/spawn.mjs | 6 +- target/esm/zurk.mjs | 3 + 10 files changed, 410 insertions(+), 11 deletions(-) create mode 100644 src/main/ts/error.ts create mode 100644 target/dts/error.d.ts diff --git a/package.json b/package.json index 546e704..061415d 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,12 @@ "import": "./target/esm/index.mjs", "default": "./target/esm/index.mjs" }, + "./error": { + "types": "./target/dts/error.d.ts", + "require": "./target/cjs/error.cjs", + "import": "./target/esm/error.mjs", + "default": "./target/esm/error.mjs" + }, "./spawn": { "types": "./target/dts/spawn.d.ts", "require": "./target/cjs/spawn.cjs", diff --git a/src/main/ts/error.ts b/src/main/ts/error.ts new file mode 100644 index 0000000..6de5a5f --- /dev/null +++ b/src/main/ts/error.ts @@ -0,0 +1,209 @@ +export const EXIT_CODES = { + 2: 'Misuse of shell builtins', + 126: 'Invoked command cannot execute', + 127: 'Command not found', + 128: 'Invalid exit argument', + 129: 'Hangup', + 130: 'Interrupt', + 131: 'Quit and dump core', + 132: 'Illegal instruction', + 133: 'Trace/breakpoint trap', + 134: 'Process aborted', + 135: 'Bus error: "access to undefined portion of memory object"', + 136: 'Floating point exception: "erroneous arithmetic operation"', + 137: 'Kill (terminate immediately)', + 138: 'User-defined 1', + 139: 'Segmentation violation', + 140: 'User-defined 2', + 141: 'Write to pipe with no one reading', + 142: 'Signal raised by alarm', + 143: 'Termination (request to terminate)', + 145: 'Child process terminated, stopped (or continued*)', + 146: 'Continue if stopped', + 147: 'Stop executing temporarily', + 148: 'Terminal stop signal', + 149: 'Background process attempting to read from tty ("in")', + 150: 'Background process attempting to write to tty ("out")', + 151: 'Urgent data available on socket', + 152: 'CPU time limit exceeded', + 153: 'File size limit exceeded', + 154: 'Signal raised by timer counting virtual time: "virtual timer expired"', + 155: 'Profiling timer expired', + 157: 'Pollable event', + 159: 'Bad syscall', +} + +export const ERRNO_CODES = { + 0: 'Success', + 1: 'Not super-user', + 2: 'No such file or directory', + 3: 'No such process', + 4: 'Interrupted system call', + 5: 'I/O error', + 6: 'No such device or address', + 7: 'Arg list too long', + 8: 'Exec format error', + 9: 'Bad file number', + 10: 'No children', + 11: 'No more processes', + 12: 'Not enough core', + 13: 'Permission denied', + 14: 'Bad address', + 15: 'Block device required', + 16: 'Mount device busy', + 17: 'File exists', + 18: 'Cross-device link', + 19: 'No such device', + 20: 'Not a directory', + 21: 'Is a directory', + 22: 'Invalid argument', + 23: 'Too many open files in system', + 24: 'Too many open files', + 25: 'Not a typewriter', + 26: 'Text file busy', + 27: 'File too large', + 28: 'No space left on device', + 29: 'Illegal seek', + 30: 'Read only file system', + 31: 'Too many links', + 32: 'Broken pipe', + 33: 'Math arg out of domain of func', + 34: 'Math result not representable', + 35: 'File locking deadlock error', + 36: 'File or path name too long', + 37: 'No record locks available', + 38: 'Function not implemented', + 39: 'Directory not empty', + 40: 'Too many symbolic links', + 42: 'No message of desired type', + 43: 'Identifier removed', + 44: 'Channel number out of range', + 45: 'Level 2 not synchronized', + 46: 'Level 3 halted', + 47: 'Level 3 reset', + 48: 'Link number out of range', + 49: 'Protocol driver not attached', + 50: 'No CSI structure available', + 51: 'Level 2 halted', + 52: 'Invalid exchange', + 53: 'Invalid request descriptor', + 54: 'Exchange full', + 55: 'No anode', + 56: 'Invalid request code', + 57: 'Invalid slot', + 59: 'Bad font file fmt', + 60: 'Device not a stream', + 61: 'No data (for no delay io)', + 62: 'Timer expired', + 63: 'Out of streams resources', + 64: 'Machine is not on the network', + 65: 'Package not installed', + 66: 'The object is remote', + 67: 'The link has been severed', + 68: 'Advertise error', + 69: 'Srmount error', + 70: 'Communication error on send', + 71: 'Protocol error', + 72: 'Multihop attempted', + 73: 'Cross mount point (not really error)', + 74: 'Trying to read unreadable message', + 75: 'Value too large for defined data type', + 76: 'Given log. name not unique', + 77: 'f.d. invalid for this operation', + 78: 'Remote address changed', + 79: 'Can access a needed shared lib', + 80: 'Accessing a corrupted shared lib', + 81: '.lib section in a.out corrupted', + 82: 'Attempting to link in too many libs', + 83: 'Attempting to exec a shared library', + 84: 'Illegal byte sequence', + 86: 'Streams pipe error', + 87: 'Too many users', + 88: 'Socket operation on non-socket', + 89: 'Destination address required', + 90: 'Message too long', + 91: 'Protocol wrong type for socket', + 92: 'Protocol not available', + 93: 'Unknown protocol', + 94: 'Socket type not supported', + 95: 'Not supported', + 96: 'Protocol family not supported', + 97: 'Address family not supported by protocol family', + 98: 'Address already in use', + 99: 'Address not available', + 100: 'Network interface is not configured', + 101: 'Network is unreachable', + 102: 'Connection reset by network', + 103: 'Connection aborted', + 104: 'Connection reset by peer', + 105: 'No buffer space available', + 106: 'Socket is already connected', + 107: 'Socket is not connected', + 108: "Can't send after socket shutdown", + 109: 'Too many references', + 110: 'Connection timed out', + 111: 'Connection refused', + 112: 'Host is down', + 113: 'Host is unreachable', + 114: 'Socket already connected', + 115: 'Connection already in progress', + 116: 'Stale file handle', + 122: 'Quota exceeded', + 123: 'No medium (in tape drive)', + 125: 'Operation canceled', + 130: 'Previous owner died', + 131: 'State not recoverable', +} + +export function getErrnoMessage(errno?: number): string { + return ( + ERRNO_CODES[-(errno as number) as keyof typeof ERRNO_CODES] || + 'Unknown error' + ) +} + +export function getExitCodeInfo(exitCode: number | null): string | undefined { + return EXIT_CODES[exitCode as keyof typeof EXIT_CODES] +} + +export const getExitMessage = ( + code: number | null, + signal: NodeJS.Signals | null, + stderr: string, + from: string +) => { + let message = `exit code: ${code}` + if (code != 0 || signal != null) { + message = `${stderr || '\n'} at ${from}` + message += `\n exit code: ${code}${ + getExitCodeInfo(code) ? ' (' + getExitCodeInfo(code) + ')' : '' + }` + if (signal != null) { + message += `\n signal: ${signal}` + } + } + + return message +} + +export const getErrorMessage = (err: NodeJS.ErrnoException, from: string) => { + return ( + `${err.message}\n` + + ` errno: ${err.errno} (${getErrnoMessage(err.errno)})\n` + + ` code: ${err.code}\n` + + ` at ${from}` + ) +} + +export function getCallerLocation(err = new Error()) { + return getCallerLocationFromString(err.stack) +} + +export function getCallerLocationFromString(stackString = 'unknown') { + return ( + stackString + .split(/^\s*(at\s)?/m) + .filter((s) => s?.includes(':'))[2] + ?.trim() || stackString + ) +} diff --git a/src/main/ts/spawn.ts b/src/main/ts/spawn.ts index c3f479b..4726c52 100644 --- a/src/main/ts/spawn.ts +++ b/src/main/ts/spawn.ts @@ -33,6 +33,7 @@ export type TSpawnResult = { ctx: TSpawnCtxNormalized error?: TSpawnError, child?: TChild + stack: string } export type TSpawnListeners = { @@ -77,6 +78,7 @@ export interface TSpawnCtxNormalized { fulfilled?: TSpawnResult error?: any run: (cb: () => void, ctx: TSpawnCtxNormalized) => void + stack: string } export const defaults: TSpawnCtxNormalized = { @@ -102,7 +104,8 @@ export const defaults: TSpawnCtxNormalized = { get stdout(){ return new VoidStream() }, get stderr(){ return new VoidStream() }, stdio: ['pipe', 'pipe', 'pipe'], - run: immediate + run: immediate, + stack: '' } export const normalizeCtx = (...ctxs: TSpawnCtx[]): TSpawnCtxNormalized => assign({ @@ -184,7 +187,8 @@ export const invoke = (c: TSpawnCtxNormalized): TSpawnCtxNormalized => { get stdall() { return c.store.stdall.join('') }, stdio, duration: Date.now() - now, - ctx: c + stack: c.stack, + ctx: c }) c.ee.emit('end', c.fulfilled, c) @@ -238,7 +242,8 @@ export const invoke = (c: TSpawnCtxNormalized): TSpawnCtxNormalized => { get stdall() { return c.store.stdall.join('') }, stdio, duration: Date.now() - now, - ctx: c + stack: c.stack, + ctx: c } opts.signal?.removeEventListener('abort', onAbort) c.callback(error, c.fulfilled) @@ -251,14 +256,15 @@ export const invoke = (c: TSpawnCtxNormalized): TSpawnCtxNormalized => { error, c.fulfilled = { error, - status: null, - signal: null, - stdout: '', - stderr: '', - stdall: '', + status: null, + signal: null, + stdout: '', + stderr: '', + stdall: '', stdio, duration: Date.now() - now, - ctx: c + stack: c.stack, + ctx: c } ) c.ee.emit('err', error, c) diff --git a/src/main/ts/zurk.ts b/src/main/ts/zurk.ts index dae616a..aa505d9 100644 --- a/src/main/ts/zurk.ts +++ b/src/main/ts/zurk.ts @@ -136,6 +136,7 @@ class Zurk implements TZurk { this.ctx.stdout, this.ctx.stderr ]} + get stack() { return this.ctx.stack } get duration() { return this.ctx.fulfilled?.duration ?? 0 } toString(){ return this.stdall.trim() } valueOf(){ return this.stdall.trim() } diff --git a/target/cjs/spawn.cjs b/target/cjs/spawn.cjs index 7255d91..759f090 100644 --- a/target/cjs/spawn.cjs +++ b/target/cjs/spawn.cjs @@ -71,7 +71,8 @@ var defaults = { return new VoidStream(); }, stdio: ["pipe", "pipe", "pipe"], - run: import_util.immediate + run: import_util.immediate, + stack: "" }; var normalizeCtx = (...ctxs) => (0, import_util.assign)( __spreadProps(__spreadValues({}, defaults), { @@ -154,6 +155,7 @@ var invoke = (c) => { }, stdio, duration: Date.now() - now, + stack: c.stack, ctx: c })); c.ee.emit("end", c.fulfilled, c); @@ -208,6 +210,7 @@ var invoke = (c) => { }, stdio, duration: Date.now() - now, + stack: c.stack, ctx: c }; (_a3 = opts.signal) == null ? void 0 : _a3.removeEventListener("abort", onAbort); @@ -228,6 +231,7 @@ var invoke = (c) => { stdall: "", stdio, duration: Date.now() - now, + stack: c.stack, ctx: c } ); diff --git a/target/cjs/zurk.cjs b/target/cjs/zurk.cjs index f8e2ee0..7b8fc21 100644 --- a/target/cjs/zurk.cjs +++ b/target/cjs/zurk.cjs @@ -132,6 +132,9 @@ var Zurk = class { this.ctx.stderr ]; } + get stack() { + return this.ctx.stack; + } get duration() { var _a2, _b; return (_b = (_a2 = this.ctx.fulfilled) == null ? void 0 : _a2.duration) != null ? _b : 0; diff --git a/target/dts/error.d.ts b/target/dts/error.d.ts new file mode 100644 index 0000000..7be5ac8 --- /dev/null +++ b/target/dts/error.d.ts @@ -0,0 +1,161 @@ +export declare const EXIT_CODES: { + 2: string; + 126: string; + 127: string; + 128: string; + 129: string; + 130: string; + 131: string; + 132: string; + 133: string; + 134: string; + 135: string; + 136: string; + 137: string; + 138: string; + 139: string; + 140: string; + 141: string; + 142: string; + 143: string; + 145: string; + 146: string; + 147: string; + 148: string; + 149: string; + 150: string; + 151: string; + 152: string; + 153: string; + 154: string; + 155: string; + 157: string; + 159: string; +}; +export declare const ERRNO_CODES: { + 0: string; + 1: string; + 2: string; + 3: string; + 4: string; + 5: string; + 6: string; + 7: string; + 8: string; + 9: string; + 10: string; + 11: string; + 12: string; + 13: string; + 14: string; + 15: string; + 16: string; + 17: string; + 18: string; + 19: string; + 20: string; + 21: string; + 22: string; + 23: string; + 24: string; + 25: string; + 26: string; + 27: string; + 28: string; + 29: string; + 30: string; + 31: string; + 32: string; + 33: string; + 34: string; + 35: string; + 36: string; + 37: string; + 38: string; + 39: string; + 40: string; + 42: string; + 43: string; + 44: string; + 45: string; + 46: string; + 47: string; + 48: string; + 49: string; + 50: string; + 51: string; + 52: string; + 53: string; + 54: string; + 55: string; + 56: string; + 57: string; + 59: string; + 60: string; + 61: string; + 62: string; + 63: string; + 64: string; + 65: string; + 66: string; + 67: string; + 68: string; + 69: string; + 70: string; + 71: string; + 72: string; + 73: string; + 74: string; + 75: string; + 76: string; + 77: string; + 78: string; + 79: string; + 80: string; + 81: string; + 82: string; + 83: string; + 84: string; + 86: string; + 87: string; + 88: string; + 89: string; + 90: string; + 91: string; + 92: string; + 93: string; + 94: string; + 95: string; + 96: string; + 97: string; + 98: string; + 99: string; + 100: string; + 101: string; + 102: string; + 103: string; + 104: string; + 105: string; + 106: string; + 107: string; + 108: string; + 109: string; + 110: string; + 111: string; + 112: string; + 113: string; + 114: string; + 115: string; + 116: string; + 122: string; + 123: string; + 125: string; + 130: string; + 131: string; +}; +export declare function getErrnoMessage(errno?: number): string; +export declare function getExitCodeInfo(exitCode: number | null): string | undefined; +export declare const getExitMessage: (code: number | null, signal: NodeJS.Signals | null, stderr: string, from: string) => string; +export declare const getErrorMessage: (err: NodeJS.ErrnoException, from: string) => string; +export declare function getCallerLocation(err?: Error): string; +export declare function getCallerLocationFromString(stackString?: string): string; diff --git a/target/dts/spawn.d.ts b/target/dts/spawn.d.ts index fdded45..3116c42 100644 --- a/target/dts/spawn.d.ts +++ b/target/dts/spawn.d.ts @@ -30,6 +30,7 @@ export type TSpawnResult = { ctx: TSpawnCtxNormalized; error?: TSpawnError; child?: TChild; + stack: string; }; export type TSpawnListeners = { start: (data: TChild, ctx: TSpawnCtxNormalized) => void; @@ -69,6 +70,7 @@ export interface TSpawnCtxNormalized { fulfilled?: TSpawnResult; error?: any; run: (cb: () => void, ctx: TSpawnCtxNormalized) => void; + stack: string; } export declare const defaults: TSpawnCtxNormalized; export declare const normalizeCtx: (...ctxs: TSpawnCtx[]) => TSpawnCtxNormalized; diff --git a/target/esm/spawn.mjs b/target/esm/spawn.mjs index 8105bd9..6e4a17a 100644 --- a/target/esm/spawn.mjs +++ b/target/esm/spawn.mjs @@ -47,7 +47,8 @@ var defaults = { return new VoidStream(); }, stdio: ["pipe", "pipe", "pipe"], - run: immediate + run: immediate, + stack: "" }; var normalizeCtx = (...ctxs) => assign( { @@ -133,6 +134,7 @@ var invoke = (c) => { }, stdio, duration: Date.now() - now, + stack: c.stack, ctx: c }); c.ee.emit("end", c.fulfilled, c); @@ -187,6 +189,7 @@ var invoke = (c) => { }, stdio, duration: Date.now() - now, + stack: c.stack, ctx: c }; (_a3 = opts.signal) == null ? void 0 : _a3.removeEventListener("abort", onAbort); @@ -207,6 +210,7 @@ var invoke = (c) => { stdall: "", stdio, duration: Date.now() - now, + stack: c.stack, ctx: c } ); diff --git a/target/esm/zurk.mjs b/target/esm/zurk.mjs index 19625f3..cb3c387 100644 --- a/target/esm/zurk.mjs +++ b/target/esm/zurk.mjs @@ -119,6 +119,9 @@ var Zurk = class { this.ctx.stderr ]; } + get stack() { + return this.ctx.stack; + } get duration() { var _a2, _b; return (_b = (_a2 = this.ctx.fulfilled) == null ? void 0 : _a2.duration) != null ? _b : 0; From 7f42b6b02f6b946f24830bd048bc4300f75cc0c6 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Fri, 6 Dec 2024 18:21:45 +0300 Subject: [PATCH 2/3] feat: apply formatting to $ error messages --- src/main/ts/error.ts | 6 +- src/main/ts/x.ts | 2 + src/main/ts/zurk.ts | 12 ++- src/test/ts/error.test.ts | 28 ++++++ src/test/ts/x.test.ts | 14 +-- target/cjs/zurk.cjs | 191 +++++++++++++++++++++++++++++++++++++- target/dts/error.d.ts | 4 +- target/esm/zurk.mjs | 191 +++++++++++++++++++++++++++++++++++++- 8 files changed, 428 insertions(+), 20 deletions(-) create mode 100644 src/test/ts/error.test.ts diff --git a/src/main/ts/error.ts b/src/main/ts/error.ts index 6de5a5f..698be75 100644 --- a/src/main/ts/error.ts +++ b/src/main/ts/error.ts @@ -166,7 +166,7 @@ export function getExitCodeInfo(exitCode: number | null): string | undefined { return EXIT_CODES[exitCode as keyof typeof EXIT_CODES] } -export const getExitMessage = ( +export const formatExitMessage = ( code: number | null, signal: NodeJS.Signals | null, stderr: string, @@ -186,7 +186,7 @@ export const getExitMessage = ( return message } -export const getErrorMessage = (err: NodeJS.ErrnoException, from: string) => { +export const formatErrorMessage = (err: NodeJS.ErrnoException, from: string) => { return ( `${err.message}\n` + ` errno: ${err.errno} (${getErrnoMessage(err.errno)})\n` + @@ -195,7 +195,7 @@ export const getErrorMessage = (err: NodeJS.ErrnoException, from: string) => { ) } -export function getCallerLocation(err = new Error()) { +export function getCallerLocation(err = new Error('zurk error')) { return getCallerLocationFromString(err.stack) } diff --git a/src/main/ts/x.ts b/src/main/ts/x.ts index 81b77c7..7253125 100644 --- a/src/main/ts/x.ts +++ b/src/main/ts/x.ts @@ -21,6 +21,7 @@ import { g, immediate } from './util.js' +import { getCallerLocation } from './error.ts' import { pipeMixin } from './mixin/pipe.js' import { killMixin } from './mixin/kill.js' import { timeoutMixin } from './mixin/timeout.js' @@ -90,6 +91,7 @@ export interface TShellSync { export const $: TShell = function(this: any, pieces?: any, ...args: any): any { const self = (this !== g) && this const preset = self || {} + preset.stack = (preset.stack || getCallerLocation()) if (pieces === undefined) return applyMixins($, preset) diff --git a/src/main/ts/zurk.ts b/src/main/ts/zurk.ts index aa505d9..4f145b0 100644 --- a/src/main/ts/zurk.ts +++ b/src/main/ts/zurk.ts @@ -12,6 +12,10 @@ import { type Promisified, type TVoidCallback } from './util.js' +import { + formatErrorMessage, + formatExitMessage +} from './error.js' export const ZURK = Symbol('Zurk') export const ZURKPROXY = Symbol('ZurkProxy') @@ -91,6 +95,7 @@ export const zurkifyPromise = (target: Promise | TZurkPromise, ctx: TSpaw if (p === 'stdio') return ctx.stdio if (p === 'ctx') return ctx if (p === 'child') return ctx.child + if (p === 'stack') return ctx.stack if (p === 'on') return function (name: string, cb: VoidFunction){ ctx.ee.on(name, cb); return proxy } if (p in target) return Reflect.get(target, p, receiver) @@ -103,9 +108,10 @@ export const zurkifyPromise = (target: Promise | TZurkPromise, ctx: TSpaw } export const getError = (data: TSpawnResult): Error | null => { - if (data.error) return data.error - if (data.status) return new Error(`Command failed with exit code ${data.status}`) - if (data.signal) return new Error(`Command failed with signal ${data.signal}`) + if (data.error) + return new Error(formatErrorMessage(data.error, data.stack)) + if (data.status || data.signal) + return new Error(formatExitMessage(data.status, data.signal, data.stderr, data.stack)) return null } diff --git a/src/test/ts/error.test.ts b/src/test/ts/error.test.ts new file mode 100644 index 0000000..28af1e4 --- /dev/null +++ b/src/test/ts/error.test.ts @@ -0,0 +1,28 @@ +import * as assert from 'node:assert' +import { describe, it } from 'node:test' +import { + getCallerLocation, + getCallerLocationFromString, + getExitCodeInfo, + getErrnoMessage, + formatErrorMessage, + formatExitMessage, + EXIT_CODES, + ERRNO_CODES +} from '../../main/ts/error.js' + +import * as all from '../../main/ts/error.js' + +describe('error', () => { + it('has proper exports', () => { + assert.equal(typeof getCallerLocation, 'function') + assert.equal(typeof getCallerLocationFromString, 'function') + assert.equal(typeof getExitCodeInfo, 'function') + assert.equal(typeof getErrnoMessage, 'function') + assert.equal(typeof formatErrorMessage, 'function') + assert.equal(typeof formatExitMessage, 'function') + assert.equal(typeof EXIT_CODES, 'object') + assert.equal(typeof ERRNO_CODES, 'object') + assert.equal(Object.keys(all).length, 8) + }) +}) diff --git a/src/test/ts/x.test.ts b/src/test/ts/x.test.ts index 8be7195..71a149f 100644 --- a/src/test/ts/x.test.ts +++ b/src/test/ts/x.test.ts @@ -25,7 +25,8 @@ describe('$()', () => { try { await $`exit 2` } catch (error: unknown) { - assert.equal((error as Error).message, 'Command failed with exit code 2') + console.error(error) + assert.ok((error as Error).message.includes('exit code: 2 (Misuse of shell builtins)')) } }) @@ -40,7 +41,7 @@ describe('$()', () => { try { $({sync: true})`exit 2` } catch (error: unknown) { - assert.equal((error as Error).message, 'Command failed with exit code 2') + assert.match((error as Error).message, /exit code: 2 \(Misuse of shell builtins\)/) } }) @@ -103,7 +104,7 @@ describe('mixins', () => { const signal = await killed assert.equal(signal, 'SIGTERM') - assert.equal(error.message, 'Command failed with signal SIGTERM') + assert.ok(error.message.includes('signal: SIGTERM')) }) it('handles `abort`', async () => { @@ -119,7 +120,8 @@ describe('mixins', () => { const { error } = await p assert.ok(getEventListeners(p.ctx.signal, 'abort').length < c) - assert.equal(error.message, 'The operation was aborted') + assert.ok(error.message.startsWith('The operation was aborted')) + assert.match(error.message, /code: ABORT_ERR/) assert.deepEqual(events, ['abort', 'end']) }) }) @@ -129,7 +131,7 @@ describe('mixins', () => { const p = $({ timeout: 25, timeoutSignal: 'SIGALRM', nothrow: true })`sleep 10` const { error } = await p - assert.equal(error.message, 'Command failed with signal SIGALRM') + assert.ok(error.message.includes('signal: SIGALRM')) }) it('handles `timeout` as promise setter', async () => { @@ -139,7 +141,7 @@ describe('mixins', () => { p.ctx.nothrow = true const { error } = await p - assert.equal(error.message, 'Command failed with signal SIGALRM') + assert.ok(error.message.includes('signal: SIGALRM')) }) }) diff --git a/target/cjs/zurk.cjs b/target/cjs/zurk.cjs index 7b8fc21..29aec18 100644 --- a/target/cjs/zurk.cjs +++ b/target/cjs/zurk.cjs @@ -25,6 +25,190 @@ __export(zurk_exports, { module.exports = __toCommonJS(zurk_exports); var import_spawn = require("./spawn.cjs"); var import_util = require("./util.cjs"); + +// src/main/ts/error.ts +var EXIT_CODES = { + 2: "Misuse of shell builtins", + 126: "Invoked command cannot execute", + 127: "Command not found", + 128: "Invalid exit argument", + 129: "Hangup", + 130: "Interrupt", + 131: "Quit and dump core", + 132: "Illegal instruction", + 133: "Trace/breakpoint trap", + 134: "Process aborted", + 135: 'Bus error: "access to undefined portion of memory object"', + 136: 'Floating point exception: "erroneous arithmetic operation"', + 137: "Kill (terminate immediately)", + 138: "User-defined 1", + 139: "Segmentation violation", + 140: "User-defined 2", + 141: "Write to pipe with no one reading", + 142: "Signal raised by alarm", + 143: "Termination (request to terminate)", + 145: "Child process terminated, stopped (or continued*)", + 146: "Continue if stopped", + 147: "Stop executing temporarily", + 148: "Terminal stop signal", + 149: 'Background process attempting to read from tty ("in")', + 150: 'Background process attempting to write to tty ("out")', + 151: "Urgent data available on socket", + 152: "CPU time limit exceeded", + 153: "File size limit exceeded", + 154: 'Signal raised by timer counting virtual time: "virtual timer expired"', + 155: "Profiling timer expired", + 157: "Pollable event", + 159: "Bad syscall" +}; +var ERRNO_CODES = { + 0: "Success", + 1: "Not super-user", + 2: "No such file or directory", + 3: "No such process", + 4: "Interrupted system call", + 5: "I/O error", + 6: "No such device or address", + 7: "Arg list too long", + 8: "Exec format error", + 9: "Bad file number", + 10: "No children", + 11: "No more processes", + 12: "Not enough core", + 13: "Permission denied", + 14: "Bad address", + 15: "Block device required", + 16: "Mount device busy", + 17: "File exists", + 18: "Cross-device link", + 19: "No such device", + 20: "Not a directory", + 21: "Is a directory", + 22: "Invalid argument", + 23: "Too many open files in system", + 24: "Too many open files", + 25: "Not a typewriter", + 26: "Text file busy", + 27: "File too large", + 28: "No space left on device", + 29: "Illegal seek", + 30: "Read only file system", + 31: "Too many links", + 32: "Broken pipe", + 33: "Math arg out of domain of func", + 34: "Math result not representable", + 35: "File locking deadlock error", + 36: "File or path name too long", + 37: "No record locks available", + 38: "Function not implemented", + 39: "Directory not empty", + 40: "Too many symbolic links", + 42: "No message of desired type", + 43: "Identifier removed", + 44: "Channel number out of range", + 45: "Level 2 not synchronized", + 46: "Level 3 halted", + 47: "Level 3 reset", + 48: "Link number out of range", + 49: "Protocol driver not attached", + 50: "No CSI structure available", + 51: "Level 2 halted", + 52: "Invalid exchange", + 53: "Invalid request descriptor", + 54: "Exchange full", + 55: "No anode", + 56: "Invalid request code", + 57: "Invalid slot", + 59: "Bad font file fmt", + 60: "Device not a stream", + 61: "No data (for no delay io)", + 62: "Timer expired", + 63: "Out of streams resources", + 64: "Machine is not on the network", + 65: "Package not installed", + 66: "The object is remote", + 67: "The link has been severed", + 68: "Advertise error", + 69: "Srmount error", + 70: "Communication error on send", + 71: "Protocol error", + 72: "Multihop attempted", + 73: "Cross mount point (not really error)", + 74: "Trying to read unreadable message", + 75: "Value too large for defined data type", + 76: "Given log. name not unique", + 77: "f.d. invalid for this operation", + 78: "Remote address changed", + 79: "Can access a needed shared lib", + 80: "Accessing a corrupted shared lib", + 81: ".lib section in a.out corrupted", + 82: "Attempting to link in too many libs", + 83: "Attempting to exec a shared library", + 84: "Illegal byte sequence", + 86: "Streams pipe error", + 87: "Too many users", + 88: "Socket operation on non-socket", + 89: "Destination address required", + 90: "Message too long", + 91: "Protocol wrong type for socket", + 92: "Protocol not available", + 93: "Unknown protocol", + 94: "Socket type not supported", + 95: "Not supported", + 96: "Protocol family not supported", + 97: "Address family not supported by protocol family", + 98: "Address already in use", + 99: "Address not available", + 100: "Network interface is not configured", + 101: "Network is unreachable", + 102: "Connection reset by network", + 103: "Connection aborted", + 104: "Connection reset by peer", + 105: "No buffer space available", + 106: "Socket is already connected", + 107: "Socket is not connected", + 108: "Can't send after socket shutdown", + 109: "Too many references", + 110: "Connection timed out", + 111: "Connection refused", + 112: "Host is down", + 113: "Host is unreachable", + 114: "Socket already connected", + 115: "Connection already in progress", + 116: "Stale file handle", + 122: "Quota exceeded", + 123: "No medium (in tape drive)", + 125: "Operation canceled", + 130: "Previous owner died", + 131: "State not recoverable" +}; +function getErrnoMessage(errno) { + return ERRNO_CODES[-errno] || "Unknown error"; +} +function getExitCodeInfo(exitCode) { + return EXIT_CODES[exitCode]; +} +var formatExitMessage = (code, signal, stderr, from) => { + let message = `exit code: ${code}`; + if (code != 0 || signal != null) { + message = `${stderr || "\n"} at ${from}`; + message += ` + exit code: ${code}${getExitCodeInfo(code) ? " (" + getExitCodeInfo(code) + ")" : ""}`; + if (signal != null) { + message += ` + signal: ${signal}`; + } + } + return message; +}; +var formatErrorMessage = (err, from) => { + return `${err.message} + errno: ${err.errno} (${getErrnoMessage(err.errno)}) + code: ${err.code} + at ${from}`; +}; + +// src/main/ts/zurk.ts var ZURK = Symbol("Zurk"); var ZURKPROXY = Symbol("ZurkProxy"); var zurk = (opts) => opts.sync ? zurkSync(opts) : zurkAsync(opts); @@ -77,9 +261,10 @@ var zurkifyPromise = (target, ctx) => { return proxy; }; var getError = (data) => { - if (data.error) return data.error; - if (data.status) return new Error(`Command failed with exit code ${data.status}`); - if (data.signal) return new Error(`Command failed with signal ${data.signal}`); + if (data.error) + return new Error(formatErrorMessage(data.error, data.stack)); + if (data.status || data.signal) + return new Error(formatExitMessage(data.status, data.signal, data.stderr, data.stack)); return null; }; var isZurkAny = (o) => (o == null ? void 0 : o[ZURK]) === ZURK; diff --git a/target/dts/error.d.ts b/target/dts/error.d.ts index 7be5ac8..8c40b9d 100644 --- a/target/dts/error.d.ts +++ b/target/dts/error.d.ts @@ -155,7 +155,7 @@ export declare const ERRNO_CODES: { }; export declare function getErrnoMessage(errno?: number): string; export declare function getExitCodeInfo(exitCode: number | null): string | undefined; -export declare const getExitMessage: (code: number | null, signal: NodeJS.Signals | null, stderr: string, from: string) => string; -export declare const getErrorMessage: (err: NodeJS.ErrnoException, from: string) => string; +export declare const formatExitMessage: (code: number | null, signal: NodeJS.Signals | null, stderr: string, from: string) => string; +export declare const formatErrorMessage: (err: NodeJS.ErrnoException, from: string) => string; export declare function getCallerLocation(err?: Error): string; export declare function getCallerLocationFromString(stackString?: string): string; diff --git a/target/esm/zurk.mjs b/target/esm/zurk.mjs index cb3c387..ae0ec43 100644 --- a/target/esm/zurk.mjs +++ b/target/esm/zurk.mjs @@ -12,6 +12,190 @@ import { isPromiseLike, makeDeferred } from "./util.mjs"; + +// src/main/ts/error.ts +var EXIT_CODES = { + 2: "Misuse of shell builtins", + 126: "Invoked command cannot execute", + 127: "Command not found", + 128: "Invalid exit argument", + 129: "Hangup", + 130: "Interrupt", + 131: "Quit and dump core", + 132: "Illegal instruction", + 133: "Trace/breakpoint trap", + 134: "Process aborted", + 135: 'Bus error: "access to undefined portion of memory object"', + 136: 'Floating point exception: "erroneous arithmetic operation"', + 137: "Kill (terminate immediately)", + 138: "User-defined 1", + 139: "Segmentation violation", + 140: "User-defined 2", + 141: "Write to pipe with no one reading", + 142: "Signal raised by alarm", + 143: "Termination (request to terminate)", + 145: "Child process terminated, stopped (or continued*)", + 146: "Continue if stopped", + 147: "Stop executing temporarily", + 148: "Terminal stop signal", + 149: 'Background process attempting to read from tty ("in")', + 150: 'Background process attempting to write to tty ("out")', + 151: "Urgent data available on socket", + 152: "CPU time limit exceeded", + 153: "File size limit exceeded", + 154: 'Signal raised by timer counting virtual time: "virtual timer expired"', + 155: "Profiling timer expired", + 157: "Pollable event", + 159: "Bad syscall" +}; +var ERRNO_CODES = { + 0: "Success", + 1: "Not super-user", + 2: "No such file or directory", + 3: "No such process", + 4: "Interrupted system call", + 5: "I/O error", + 6: "No such device or address", + 7: "Arg list too long", + 8: "Exec format error", + 9: "Bad file number", + 10: "No children", + 11: "No more processes", + 12: "Not enough core", + 13: "Permission denied", + 14: "Bad address", + 15: "Block device required", + 16: "Mount device busy", + 17: "File exists", + 18: "Cross-device link", + 19: "No such device", + 20: "Not a directory", + 21: "Is a directory", + 22: "Invalid argument", + 23: "Too many open files in system", + 24: "Too many open files", + 25: "Not a typewriter", + 26: "Text file busy", + 27: "File too large", + 28: "No space left on device", + 29: "Illegal seek", + 30: "Read only file system", + 31: "Too many links", + 32: "Broken pipe", + 33: "Math arg out of domain of func", + 34: "Math result not representable", + 35: "File locking deadlock error", + 36: "File or path name too long", + 37: "No record locks available", + 38: "Function not implemented", + 39: "Directory not empty", + 40: "Too many symbolic links", + 42: "No message of desired type", + 43: "Identifier removed", + 44: "Channel number out of range", + 45: "Level 2 not synchronized", + 46: "Level 3 halted", + 47: "Level 3 reset", + 48: "Link number out of range", + 49: "Protocol driver not attached", + 50: "No CSI structure available", + 51: "Level 2 halted", + 52: "Invalid exchange", + 53: "Invalid request descriptor", + 54: "Exchange full", + 55: "No anode", + 56: "Invalid request code", + 57: "Invalid slot", + 59: "Bad font file fmt", + 60: "Device not a stream", + 61: "No data (for no delay io)", + 62: "Timer expired", + 63: "Out of streams resources", + 64: "Machine is not on the network", + 65: "Package not installed", + 66: "The object is remote", + 67: "The link has been severed", + 68: "Advertise error", + 69: "Srmount error", + 70: "Communication error on send", + 71: "Protocol error", + 72: "Multihop attempted", + 73: "Cross mount point (not really error)", + 74: "Trying to read unreadable message", + 75: "Value too large for defined data type", + 76: "Given log. name not unique", + 77: "f.d. invalid for this operation", + 78: "Remote address changed", + 79: "Can access a needed shared lib", + 80: "Accessing a corrupted shared lib", + 81: ".lib section in a.out corrupted", + 82: "Attempting to link in too many libs", + 83: "Attempting to exec a shared library", + 84: "Illegal byte sequence", + 86: "Streams pipe error", + 87: "Too many users", + 88: "Socket operation on non-socket", + 89: "Destination address required", + 90: "Message too long", + 91: "Protocol wrong type for socket", + 92: "Protocol not available", + 93: "Unknown protocol", + 94: "Socket type not supported", + 95: "Not supported", + 96: "Protocol family not supported", + 97: "Address family not supported by protocol family", + 98: "Address already in use", + 99: "Address not available", + 100: "Network interface is not configured", + 101: "Network is unreachable", + 102: "Connection reset by network", + 103: "Connection aborted", + 104: "Connection reset by peer", + 105: "No buffer space available", + 106: "Socket is already connected", + 107: "Socket is not connected", + 108: "Can't send after socket shutdown", + 109: "Too many references", + 110: "Connection timed out", + 111: "Connection refused", + 112: "Host is down", + 113: "Host is unreachable", + 114: "Socket already connected", + 115: "Connection already in progress", + 116: "Stale file handle", + 122: "Quota exceeded", + 123: "No medium (in tape drive)", + 125: "Operation canceled", + 130: "Previous owner died", + 131: "State not recoverable" +}; +function getErrnoMessage(errno) { + return ERRNO_CODES[-errno] || "Unknown error"; +} +function getExitCodeInfo(exitCode) { + return EXIT_CODES[exitCode]; +} +var formatExitMessage = (code, signal, stderr, from) => { + let message = `exit code: ${code}`; + if (code != 0 || signal != null) { + message = `${stderr || "\n"} at ${from}`; + message += ` + exit code: ${code}${getExitCodeInfo(code) ? " (" + getExitCodeInfo(code) + ")" : ""}`; + if (signal != null) { + message += ` + signal: ${signal}`; + } + } + return message; +}; +var formatErrorMessage = (err, from) => { + return `${err.message} + errno: ${err.errno} (${getErrnoMessage(err.errno)}) + code: ${err.code} + at ${from}`; +}; + +// src/main/ts/zurk.ts var ZURK = Symbol("Zurk"); var ZURKPROXY = Symbol("ZurkProxy"); var zurk = (opts) => opts.sync ? zurkSync(opts) : zurkAsync(opts); @@ -64,9 +248,10 @@ var zurkifyPromise = (target, ctx) => { return proxy; }; var getError = (data) => { - if (data.error) return data.error; - if (data.status) return new Error(`Command failed with exit code ${data.status}`); - if (data.signal) return new Error(`Command failed with signal ${data.signal}`); + if (data.error) + return new Error(formatErrorMessage(data.error, data.stack)); + if (data.status || data.signal) + return new Error(formatExitMessage(data.status, data.signal, data.stderr, data.stack)); return null; }; var isZurkAny = (o) => (o == null ? void 0 : o[ZURK]) === ZURK; From 9d51cdf4b09009efccf0ada691d1c532fe843de7 Mon Sep 17 00:00:00 2001 From: Anton Golub Date: Fri, 6 Dec 2024 18:28:08 +0300 Subject: [PATCH 3/3] chore: shrink extra bytes --- src/main/ts/spawn.ts | 4 ---- src/main/ts/zurk.ts | 12 +++++------- target/cjs/index.cjs | 10 ++++++++++ target/cjs/spawn.cjs | 3 --- target/cjs/zurk.cjs | 13 +++++-------- target/dts/spawn.d.ts | 1 - target/dts/zurk.d.ts | 2 +- target/esm/index.mjs | 10 ++++++++++ target/esm/spawn.mjs | 3 --- target/esm/zurk.mjs | 13 +++++-------- 10 files changed, 36 insertions(+), 35 deletions(-) diff --git a/src/main/ts/spawn.ts b/src/main/ts/spawn.ts index 4726c52..e4582b5 100644 --- a/src/main/ts/spawn.ts +++ b/src/main/ts/spawn.ts @@ -33,7 +33,6 @@ export type TSpawnResult = { ctx: TSpawnCtxNormalized error?: TSpawnError, child?: TChild - stack: string } export type TSpawnListeners = { @@ -187,7 +186,6 @@ export const invoke = (c: TSpawnCtxNormalized): TSpawnCtxNormalized => { get stdall() { return c.store.stdall.join('') }, stdio, duration: Date.now() - now, - stack: c.stack, ctx: c }) c.ee.emit('end', c.fulfilled, c) @@ -242,7 +240,6 @@ export const invoke = (c: TSpawnCtxNormalized): TSpawnCtxNormalized => { get stdall() { return c.store.stdall.join('') }, stdio, duration: Date.now() - now, - stack: c.stack, ctx: c } opts.signal?.removeEventListener('abort', onAbort) @@ -263,7 +260,6 @@ export const invoke = (c: TSpawnCtxNormalized): TSpawnCtxNormalized => { stdall: '', stdio, duration: Date.now() - now, - stack: c.stack, ctx: c } ) diff --git a/src/main/ts/zurk.ts b/src/main/ts/zurk.ts index 4f145b0..d9ea9e4 100644 --- a/src/main/ts/zurk.ts +++ b/src/main/ts/zurk.ts @@ -95,7 +95,6 @@ export const zurkifyPromise = (target: Promise | TZurkPromise, ctx: TSpaw if (p === 'stdio') return ctx.stdio if (p === 'ctx') return ctx if (p === 'child') return ctx.child - if (p === 'stack') return ctx.stack if (p === 'on') return function (name: string, cb: VoidFunction){ ctx.ee.on(name, cb); return proxy } if (p in target) return Reflect.get(target, p, receiver) @@ -107,11 +106,11 @@ export const zurkifyPromise = (target: Promise | TZurkPromise, ctx: TSpaw return proxy } -export const getError = (data: TSpawnResult): Error | null => { - if (data.error) - return new Error(formatErrorMessage(data.error, data.stack)) - if (data.status || data.signal) - return new Error(formatExitMessage(data.status, data.signal, data.stderr, data.stack)) +export const getError = (spawnResult: TSpawnResult): Error | null => { + if (spawnResult.error) + return new Error(formatErrorMessage(spawnResult.error, spawnResult.ctx.stack)) + if (spawnResult.status || spawnResult.signal) + return new Error(formatExitMessage(spawnResult.status, spawnResult.signal, spawnResult.stderr, spawnResult.ctx.stack)) return null } @@ -142,7 +141,6 @@ class Zurk implements TZurk { this.ctx.stdout, this.ctx.stderr ]} - get stack() { return this.ctx.stack } get duration() { return this.ctx.fulfilled?.duration ?? 0 } toString(){ return this.stdall.trim() } valueOf(){ return this.stdall.trim() } diff --git a/target/cjs/index.cjs b/target/cjs/index.cjs index acab54b..a020ba2 100644 --- a/target/cjs/index.cjs +++ b/target/cjs/index.cjs @@ -23,6 +23,15 @@ var import_spawn2 = require("./spawn.cjs"); var import_zurk4 = require("./zurk.cjs"); var import_util4 = require("./util.cjs"); +// src/main/ts/error.ts +function getCallerLocation(err = new Error("zurk error")) { + return getCallerLocationFromString(err.stack); +} +function getCallerLocationFromString(stackString = "unknown") { + var _a; + return ((_a = stackString.split(/^\s*(at\s)?/m).filter((s) => s == null ? void 0 : s.includes(":"))[2]) == null ? void 0 : _a.trim()) || stackString; +} + // src/main/ts/mixin/pipe.ts var import_node_stream = require("stream"); var import_util = require("./util.cjs"); @@ -126,6 +135,7 @@ var timeoutMixin = ($2, result, ctx) => { var $ = function(pieces, ...args) { const self = this !== import_util4.g && this; const preset = self || {}; + preset.stack = preset.stack || getCallerLocation(); if (pieces === void 0) return applyMixins($, preset); if ((0, import_util4.isStringLiteral)(pieces, ...args)) return ignite(preset, pieces, ...args); return (...args2) => $.apply(self ? (0, import_util4.assign)(self, pieces) : pieces, args2); diff --git a/target/cjs/spawn.cjs b/target/cjs/spawn.cjs index 759f090..f6ab523 100644 --- a/target/cjs/spawn.cjs +++ b/target/cjs/spawn.cjs @@ -155,7 +155,6 @@ var invoke = (c) => { }, stdio, duration: Date.now() - now, - stack: c.stack, ctx: c })); c.ee.emit("end", c.fulfilled, c); @@ -210,7 +209,6 @@ var invoke = (c) => { }, stdio, duration: Date.now() - now, - stack: c.stack, ctx: c }; (_a3 = opts.signal) == null ? void 0 : _a3.removeEventListener("abort", onAbort); @@ -231,7 +229,6 @@ var invoke = (c) => { stdall: "", stdio, duration: Date.now() - now, - stack: c.stack, ctx: c } ); diff --git a/target/cjs/zurk.cjs b/target/cjs/zurk.cjs index 29aec18..0454caf 100644 --- a/target/cjs/zurk.cjs +++ b/target/cjs/zurk.cjs @@ -260,11 +260,11 @@ var zurkifyPromise = (target, ctx) => { }); return proxy; }; -var getError = (data) => { - if (data.error) - return new Error(formatErrorMessage(data.error, data.stack)); - if (data.status || data.signal) - return new Error(formatExitMessage(data.status, data.signal, data.stderr, data.stack)); +var getError = (spawnResult) => { + if (spawnResult.error) + return new Error(formatErrorMessage(spawnResult.error, spawnResult.ctx.stack)); + if (spawnResult.status || spawnResult.signal) + return new Error(formatExitMessage(spawnResult.status, spawnResult.signal, spawnResult.stderr, spawnResult.ctx.stack)); return null; }; var isZurkAny = (o) => (o == null ? void 0 : o[ZURK]) === ZURK; @@ -317,9 +317,6 @@ var Zurk = class { this.ctx.stderr ]; } - get stack() { - return this.ctx.stack; - } get duration() { var _a2, _b; return (_b = (_a2 = this.ctx.fulfilled) == null ? void 0 : _a2.duration) != null ? _b : 0; diff --git a/target/dts/spawn.d.ts b/target/dts/spawn.d.ts index 3116c42..1b25c0d 100644 --- a/target/dts/spawn.d.ts +++ b/target/dts/spawn.d.ts @@ -30,7 +30,6 @@ export type TSpawnResult = { ctx: TSpawnCtxNormalized; error?: TSpawnError; child?: TChild; - stack: string; }; export type TSpawnListeners = { start: (data: TChild, ctx: TSpawnCtxNormalized) => void; diff --git a/target/dts/zurk.d.ts b/target/dts/zurk.d.ts index ab627bb..c5476fe 100644 --- a/target/dts/zurk.d.ts +++ b/target/dts/zurk.d.ts @@ -29,7 +29,7 @@ export declare const zurk: TZurkPromise; export declare const zurkSync: (opts: TZurkOptions) => TZurk; export declare const zurkifyPromise: (target: Promise | TZurkPromise, ctx: TSpawnCtxNormalized) => TZurkPromise; -export declare const getError: (data: TSpawnResult) => Error | null; +export declare const getError: (spawnResult: TSpawnResult) => Error | null; export declare const isZurkAny: (o: any) => o is TZurk | TZurkPromise; export declare const isZurk: (o: any) => o is TZurk; export declare const isZurkPromise: (o: any) => o is TZurkPromise; diff --git a/target/esm/index.mjs b/target/esm/index.mjs index 7480c6b..1ec42f9 100644 --- a/target/esm/index.mjs +++ b/target/esm/index.mjs @@ -18,6 +18,15 @@ import { immediate } from "./util.mjs"; +// src/main/ts/error.ts +function getCallerLocation(err = new Error("zurk error")) { + return getCallerLocationFromString(err.stack); +} +function getCallerLocationFromString(stackString = "unknown") { + var _a; + return ((_a = stackString.split(/^\s*(at\s)?/m).filter((s) => s == null ? void 0 : s.includes(":"))[2]) == null ? void 0 : _a.trim()) || stackString; +} + // src/main/ts/mixin/pipe.ts import { Writable } from "node:stream"; import { assign, isStringLiteral } from "./util.mjs"; @@ -121,6 +130,7 @@ var timeoutMixin = ($2, result, ctx) => { var $ = function(pieces, ...args) { const self = this !== g && this; const preset = self || {}; + preset.stack = preset.stack || getCallerLocation(); if (pieces === void 0) return applyMixins($, preset); if (isStringLiteral2(pieces, ...args)) return ignite(preset, pieces, ...args); return (...args2) => $.apply(self ? assign4(self, pieces) : pieces, args2); diff --git a/target/esm/spawn.mjs b/target/esm/spawn.mjs index 6e4a17a..62f7f7e 100644 --- a/target/esm/spawn.mjs +++ b/target/esm/spawn.mjs @@ -134,7 +134,6 @@ var invoke = (c) => { }, stdio, duration: Date.now() - now, - stack: c.stack, ctx: c }); c.ee.emit("end", c.fulfilled, c); @@ -189,7 +188,6 @@ var invoke = (c) => { }, stdio, duration: Date.now() - now, - stack: c.stack, ctx: c }; (_a3 = opts.signal) == null ? void 0 : _a3.removeEventListener("abort", onAbort); @@ -210,7 +208,6 @@ var invoke = (c) => { stdall: "", stdio, duration: Date.now() - now, - stack: c.stack, ctx: c } ); diff --git a/target/esm/zurk.mjs b/target/esm/zurk.mjs index ae0ec43..0d74f7e 100644 --- a/target/esm/zurk.mjs +++ b/target/esm/zurk.mjs @@ -247,11 +247,11 @@ var zurkifyPromise = (target, ctx) => { }); return proxy; }; -var getError = (data) => { - if (data.error) - return new Error(formatErrorMessage(data.error, data.stack)); - if (data.status || data.signal) - return new Error(formatExitMessage(data.status, data.signal, data.stderr, data.stack)); +var getError = (spawnResult) => { + if (spawnResult.error) + return new Error(formatErrorMessage(spawnResult.error, spawnResult.ctx.stack)); + if (spawnResult.status || spawnResult.signal) + return new Error(formatExitMessage(spawnResult.status, spawnResult.signal, spawnResult.stderr, spawnResult.ctx.stack)); return null; }; var isZurkAny = (o) => (o == null ? void 0 : o[ZURK]) === ZURK; @@ -304,9 +304,6 @@ var Zurk = class { this.ctx.stderr ]; } - get stack() { - return this.ctx.stack; - } get duration() { var _a2, _b; return (_b = (_a2 = this.ctx.fulfilled) == null ? void 0 : _a2.duration) != null ? _b : 0;