@idlebox/common 1.5.13 → 1.5.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/autoindex.d.ts +3 -3
- package/lib/autoindex.d.ts.map +1 -1
- package/lib/autoindex.js +4 -2
- package/lib/autoindex.js.map +1 -1
- package/lib/error/pretty.nodejs.d.ts +0 -29
- package/lib/error/pretty.nodejs.d.ts.map +1 -1
- package/lib/error/pretty.nodejs.js +157 -237
- package/lib/error/pretty.nodejs.js.map +1 -1
- package/lib/error/stack-parser.v8.d.ts +31 -0
- package/lib/error/stack-parser.v8.d.ts.map +1 -0
- package/lib/error/stack-parser.v8.js +106 -0
- package/lib/error/stack-parser.v8.js.map +1 -0
- package/package.json +7 -7
- package/src/autoindex.ts +5 -3
- package/src/error/pretty.nodejs.ts +214 -337
- package/src/error/stack-parser.v8.ts +157 -0
|
@@ -1,41 +1,14 @@
|
|
|
1
|
-
import { isAbsolute } from '../path/isAbsolute.js';
|
|
2
1
|
import { relativePath } from '../path/normalizePath.js';
|
|
3
2
|
import { globalObject } from '../platform/globalObject.js';
|
|
4
3
|
import { isNative } from '../platform/os.js';
|
|
5
4
|
import { vscEscapeValue } from './pretty.vscode.js';
|
|
5
|
+
import { parseStackLine, type IStructreStackLine } from './stack-parser.v8.js';
|
|
6
6
|
import { createStackTraceHolder } from './stack-trace.js';
|
|
7
7
|
|
|
8
8
|
const process = globalObject.process;
|
|
9
9
|
const window = globalObject.window;
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
const func_call = /(?<func_name>(?:(?:async|new) )?[^/\\\s]+) (?:\[as (?<func_alias>[^\]]+)] )?/.source;
|
|
13
|
-
// xxxx.yyyyy [as eval]
|
|
14
|
-
const line_column = /(?::(?<line>\d+))?(?::(?<column>\d+))?/.source;
|
|
15
|
-
const locationEsm = /(?<schema>node:|file:\/\/|https?:\/\/)?(?<path2>[^:]+)/.source;
|
|
16
|
-
// node:internal/modules/cjs/loader.js:883:14
|
|
17
|
-
const locationCjs = /(?<path1>(?:\/|[a-zA-Z]:)[^:]+)/.source;
|
|
18
|
-
// /data/to/file.js
|
|
19
|
-
const location = `(?:${locationCjs}|${locationEsm})${line_column}`;
|
|
20
|
-
|
|
21
|
-
const regNormal = new RegExp(`${padding}${func_call}\\(${location}\\)$`);
|
|
22
|
-
type TypeMatchNormal = 'padding' | TypeMatchNoFile | TypeMatchFileOnly;
|
|
23
|
-
|
|
24
|
-
const regNoFile = new RegExp(`${padding}${func_call}$`);
|
|
25
|
-
type TypeMatchNoFile = 'padding' | 'func_name' | 'func_alias';
|
|
26
|
-
|
|
27
|
-
const regFileOnly = new RegExp(`${padding}${location}$`);
|
|
28
|
-
type TypeMatchFileOnly = 'padding' | 'schema' | 'path1' | 'path2' | 'line' | 'column';
|
|
29
|
-
|
|
30
|
-
const regEvalItem = new RegExp(`\\(eval at ${func_call}`, 'g');
|
|
31
|
-
const eval_source = /, (?<eval_func>[\S]+):(?<eval_line>\d+):(?<eval_column>\d+)/.source;
|
|
32
|
-
const regEval = new RegExp(`${padding}${func_call}.*?\\(${location}\\)+${eval_source}`);
|
|
33
|
-
type TypeMatchEval = 'padding' | TypeMatchNoFile | TypeMatchFileOnly | 'eval_func' | 'eval_line' | 'eval_column';
|
|
34
|
-
|
|
35
|
-
const regInvalid = new RegExp(`${padding}(?<content>.+) \\(${location}\\)$`);
|
|
36
|
-
type TypeMatchInvalid = TypeMatchFileOnly | 'content';
|
|
37
|
-
|
|
38
|
-
let root = process?.cwd?.() ?? window?.location?.domain ?? '/';
|
|
11
|
+
let errorRootPath = process?.cwd?.() ?? window?.location?.domain ?? '/';
|
|
39
12
|
export function setErrorLogRoot(_root: string) {
|
|
40
13
|
if (
|
|
41
14
|
typeof process !== 'undefined' &&
|
|
@@ -44,132 +17,7 @@ export function setErrorLogRoot(_root: string) {
|
|
|
44
17
|
) {
|
|
45
18
|
process.stderr.write(`\x1B]633;P;Cwd=${vscEscapeValue(_root)}\x07`);
|
|
46
19
|
}
|
|
47
|
-
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface IFunction {
|
|
51
|
-
name: string;
|
|
52
|
-
alias?: string;
|
|
53
|
-
}
|
|
54
|
-
interface IFileLocation {
|
|
55
|
-
path: string;
|
|
56
|
-
schema: string; // '' | 'node:' | 'file:' | 'http:' | 'https:';
|
|
57
|
-
line: number;
|
|
58
|
-
column: number;
|
|
59
|
-
isAbsolute: boolean;
|
|
60
|
-
}
|
|
61
|
-
interface IEvalDef {
|
|
62
|
-
eval_func: string;
|
|
63
|
-
eval_line: number;
|
|
64
|
-
eval_column: number;
|
|
65
|
-
funcs: string[];
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
export interface IStructreStackLine {
|
|
69
|
-
invalid?: boolean;
|
|
70
|
-
special?: boolean;
|
|
71
|
-
toString(): string;
|
|
72
|
-
padding?: string;
|
|
73
|
-
func?: IFunction;
|
|
74
|
-
location?: IFileLocation;
|
|
75
|
-
eval?: IEvalDef;
|
|
76
|
-
_matches?: RegExp;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function matchLine<T extends string>(line: string, reg: RegExp): null | Record<T, string> {
|
|
80
|
-
const m = reg.exec(line);
|
|
81
|
-
if (!m) {
|
|
82
|
-
return null;
|
|
83
|
-
}
|
|
84
|
-
return m.groups as any;
|
|
85
|
-
}
|
|
86
|
-
const endingSlashes = /\/+$/;
|
|
87
|
-
function addLoc(ret: IStructreStackLine, m: Record<TypeMatchFileOnly, string>) {
|
|
88
|
-
const path = m.path1 || m.path2;
|
|
89
|
-
ret.location = {
|
|
90
|
-
schema: m.schema?.replace(endingSlashes, '') ?? '',
|
|
91
|
-
path: path,
|
|
92
|
-
line: Number.parseInt(m.line, 10),
|
|
93
|
-
column: Number.parseInt(m.column, 10),
|
|
94
|
-
isAbsolute: isAbsolute(path),
|
|
95
|
-
};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
function addFunc(ret: IStructreStackLine, m: Record<TypeMatchNoFile, string>) {
|
|
99
|
-
ret.func = {
|
|
100
|
-
name: m.func_name,
|
|
101
|
-
alias: m.func_alias,
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function parseStackLine(line: string): IStructreStackLine {
|
|
106
|
-
const __raw = line;
|
|
107
|
-
const ret: IStructreStackLine = {
|
|
108
|
-
invalid: false,
|
|
109
|
-
toString() {
|
|
110
|
-
return __raw;
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
Object.assign(ret, { __raw });
|
|
114
|
-
|
|
115
|
-
const mNormal = matchLine<TypeMatchNormal>(line, regNormal);
|
|
116
|
-
if (mNormal) {
|
|
117
|
-
ret._matches = regNormal;
|
|
118
|
-
ret.padding = mNormal.padding;
|
|
119
|
-
addFunc(ret, mNormal);
|
|
120
|
-
addLoc(ret, mNormal);
|
|
121
|
-
return ret;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
const mFile = matchLine<TypeMatchFileOnly>(line, regFileOnly);
|
|
125
|
-
if (mFile) {
|
|
126
|
-
ret._matches = regFileOnly;
|
|
127
|
-
ret.padding = mFile.padding;
|
|
128
|
-
addLoc(ret, mFile);
|
|
129
|
-
return ret;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
const mNoFile = matchLine<TypeMatchNoFile>(line, regNoFile);
|
|
133
|
-
if (mNoFile) {
|
|
134
|
-
ret._matches = regNoFile;
|
|
135
|
-
ret.padding = mNoFile.padding;
|
|
136
|
-
addFunc(ret, mNoFile);
|
|
137
|
-
return ret;
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
const mEval = matchLine<TypeMatchEval>(line.replaceAll(regEvalItem, ''), regEval);
|
|
141
|
-
if (mEval) {
|
|
142
|
-
ret._matches = regEval;
|
|
143
|
-
ret.padding = mEval.padding;
|
|
144
|
-
addFunc(ret, mEval);
|
|
145
|
-
addLoc(ret, mEval);
|
|
146
|
-
|
|
147
|
-
ret.eval = {
|
|
148
|
-
eval_column: Number.parseInt(mEval.eval_column, 10),
|
|
149
|
-
eval_func: mEval.eval_func,
|
|
150
|
-
eval_line: Number.parseInt(mEval.eval_line, 10),
|
|
151
|
-
funcs: [],
|
|
152
|
-
};
|
|
153
|
-
for (const item of line.matchAll(regEvalItem)) {
|
|
154
|
-
// biome-ignore lint/style/noNonNullAssertion: 有匹配必然有 groups
|
|
155
|
-
ret.eval.funcs.push(item.groups!['func_name']);
|
|
156
|
-
}
|
|
157
|
-
ret.eval.funcs.push(mEval.eval_func);
|
|
158
|
-
|
|
159
|
-
return ret;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const mInv = matchLine<TypeMatchInvalid>(line, regInvalid);
|
|
163
|
-
if (mInv) {
|
|
164
|
-
const path = mInv.path1 || mInv.path2;
|
|
165
|
-
if (path.endsWith(mInv.content)) {
|
|
166
|
-
addLoc(ret, mInv);
|
|
167
|
-
return ret;
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
ret.invalid = true;
|
|
172
|
-
return ret;
|
|
20
|
+
errorRootPath = _root;
|
|
173
21
|
}
|
|
174
22
|
|
|
175
23
|
function isPrettyDisabled() {
|
|
@@ -193,10 +41,34 @@ export function prettyPrintError<ErrorType extends IError = IError>(type: string
|
|
|
193
41
|
|
|
194
42
|
const columns = process?.stderr?.columns || 80;
|
|
195
43
|
const line = '-'.repeat(columns);
|
|
196
|
-
console.error(
|
|
197
|
-
|
|
198
|
-
|
|
44
|
+
console.error(line);
|
|
45
|
+
|
|
46
|
+
console.error(`[${type}] ${prettyFormatError(e, true, false)}`);
|
|
47
|
+
|
|
48
|
+
let cause = e.cause;
|
|
49
|
+
while (cause && typeof cause === 'object' && 'stack' in cause) {
|
|
50
|
+
console.error(`[Caused by] ${prettyFormatError(cause as IError, true, false)}`);
|
|
51
|
+
cause = (cause as IError).cause;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const structured = [];
|
|
55
|
+
if (isSelfPrint()) {
|
|
56
|
+
structured.push({
|
|
57
|
+
special: true,
|
|
58
|
+
toString() {
|
|
59
|
+
return '== Above error was printed at:';
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const selfStack = createStackTraceHolder('111', prettyPrintError);
|
|
64
|
+
const stackLines = selfStack.stack.split(/\n/g).slice(1);
|
|
65
|
+
structured.push(...stackLines.map(parseStackLine));
|
|
199
66
|
}
|
|
67
|
+
|
|
68
|
+
const formatter = new Formatter();
|
|
69
|
+
const txt = structured.filter(formatter.skipSomeFrame).map(formatter.translateFunction).map(formatter.stringifyLine).join('\n');
|
|
70
|
+
console.error(txt);
|
|
71
|
+
|
|
200
72
|
console.error(line);
|
|
201
73
|
|
|
202
74
|
if (!notify_printed && e.stack && e.message !== e.stack) {
|
|
@@ -212,28 +84,24 @@ function red(s: string) {
|
|
|
212
84
|
return isNative ? `\x1B[38;5;9m${s}\x1B[0m` : s;
|
|
213
85
|
}
|
|
214
86
|
|
|
215
|
-
export function parseStackString(stack: string) {
|
|
216
|
-
return stack.split('\n').map(parseStackLine);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
87
|
/**
|
|
220
88
|
* Format a stack trace for display.
|
|
221
89
|
* @param stackLines The stack lines to format.
|
|
222
90
|
*/
|
|
223
91
|
export function prettyFormatStack(stackLines: readonly string[]): string[];
|
|
224
92
|
/** @internal */
|
|
225
|
-
export function prettyFormatStack(stackLines: readonly string[], boundary
|
|
226
|
-
export function prettyFormatStack(stackLines: readonly string[], boundary: CallableFunction = prettyFormatStack): string[] {
|
|
93
|
+
export function prettyFormatStack(stackLines: readonly string[], boundary: CallableFunction | false): string[];
|
|
94
|
+
export function prettyFormatStack(stackLines: readonly string[], boundary: CallableFunction | false = prettyFormatStack): string[] {
|
|
227
95
|
if (isPrettyDisabled()) {
|
|
228
96
|
return stackLines.slice();
|
|
229
97
|
}
|
|
230
98
|
const structured: IStructreStackLine[] = stackLines.map(parseStackLine);
|
|
231
99
|
|
|
232
|
-
if (isSelfPrint()) {
|
|
100
|
+
if (boundary && isSelfPrint()) {
|
|
233
101
|
structured.push({
|
|
234
102
|
special: true,
|
|
235
103
|
toString() {
|
|
236
|
-
return '== Above error was
|
|
104
|
+
return '== Above error was formatted at:';
|
|
237
105
|
},
|
|
238
106
|
});
|
|
239
107
|
|
|
@@ -242,93 +110,8 @@ export function prettyFormatStack(stackLines: readonly string[], boundary: Calla
|
|
|
242
110
|
structured.push(...stackLines.map(parseStackLine));
|
|
243
111
|
}
|
|
244
112
|
|
|
245
|
-
|
|
246
|
-
return structured
|
|
247
|
-
.filter(skipSomeFrame)
|
|
248
|
-
.map(translateFunction)
|
|
249
|
-
.map((line) => {
|
|
250
|
-
let ret: string;
|
|
251
|
-
if (line.special) {
|
|
252
|
-
return line.toString();
|
|
253
|
-
}
|
|
254
|
-
if (line.invalid) {
|
|
255
|
-
if (messageEnded) {
|
|
256
|
-
return red(line.toString());
|
|
257
|
-
}
|
|
258
|
-
return line.toString();
|
|
259
|
-
}
|
|
260
|
-
messageEnded = true;
|
|
261
|
-
const fn_name = line.func?.name;
|
|
262
|
-
|
|
263
|
-
if (!line.location?.isAbsolute || line.location.schema === 'node:') {
|
|
264
|
-
// no-path, relative path, node:
|
|
265
|
-
ret = ' at \x1B[2m';
|
|
266
|
-
if (line.func) {
|
|
267
|
-
ret += fn_name;
|
|
268
|
-
if (line.func.alias) {
|
|
269
|
-
ret += ` [${line.func.alias}]`;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
if (line.location?.path === '<anonymous>') {
|
|
274
|
-
} else if (line.location?.path) {
|
|
275
|
-
if (fn_name) {
|
|
276
|
-
ret += ' (';
|
|
277
|
-
}
|
|
278
|
-
ret += formatFileLine(line.location.schema, line.location.path, line.location.line, line.location.column);
|
|
279
|
-
if (fn_name) {
|
|
280
|
-
ret += ')';
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
ret += '\x1B[0m';
|
|
284
|
-
} else {
|
|
285
|
-
const path = line.location.path;
|
|
286
|
-
const isNodeModule = path.includes('/node_modules/');
|
|
287
|
-
const fn_alias = line.func?.alias;
|
|
288
|
-
|
|
289
|
-
const color = fn_name ? (isNodeModule ? '14;2' : '14') : '8';
|
|
290
|
-
ret = `\x1b[0m at \x1b[38;5;${color}m`;
|
|
291
|
-
if (fn_alias && fn_name && fn_name.startsWith('Object.')) {
|
|
292
|
-
ret += `${fn_alias} [export]`;
|
|
293
|
-
} else {
|
|
294
|
-
ret += formatFunctionName(fn_name, fn_alias);
|
|
295
|
-
}
|
|
296
|
-
ret += '\x1b[0m';
|
|
297
|
-
if (line.eval) {
|
|
298
|
-
ret += `\x1b[2m(${line.eval.funcs.filter((e) => e !== '<anonymous>').join('->')})\x1b[0m`;
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if (path) {
|
|
302
|
-
let color: string;
|
|
303
|
-
if (isNodeModule) {
|
|
304
|
-
color = '\x1b[38;5;237m';
|
|
305
|
-
} else {
|
|
306
|
-
color = '\x1b[38;5;2m';
|
|
307
|
-
}
|
|
308
|
-
ret += ` (${color}`;
|
|
309
|
-
const file = formatFileLine(line.location.schema, path, line.location.line, line.location.column);
|
|
310
|
-
const lastNmPos = file.lastIndexOf('/node_modules/');
|
|
311
|
-
if (lastNmPos >= 0) {
|
|
312
|
-
ret += file.slice(0, lastNmPos + 14);
|
|
313
|
-
|
|
314
|
-
let nextSlash = file.indexOf('/', lastNmPos + 15);
|
|
315
|
-
const scopePkg = file[lastNmPos + 14] === '@';
|
|
316
|
-
if (scopePkg) {
|
|
317
|
-
nextSlash = file.indexOf('/', nextSlash + 1);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
ret += '\x1B[0m';
|
|
321
|
-
ret += file.slice(lastNmPos + 14, nextSlash);
|
|
322
|
-
ret += color;
|
|
323
|
-
ret += file.slice(nextSlash);
|
|
324
|
-
} else {
|
|
325
|
-
ret += file;
|
|
326
|
-
}
|
|
327
|
-
ret += '\x1B[0m)';
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
return ret;
|
|
331
|
-
});
|
|
113
|
+
const formatter = new Formatter();
|
|
114
|
+
return structured.filter(formatter.skipSomeFrame).map(formatter.translateFunction).map(formatter.stringifyLine);
|
|
332
115
|
}
|
|
333
116
|
|
|
334
117
|
interface IError {
|
|
@@ -350,8 +133,8 @@ const regErrorClassName = /^(\S+):/;
|
|
|
350
133
|
*/
|
|
351
134
|
export function prettyFormatError<ErrorType extends IError = IError>(e: ErrorType, withMessage?: boolean): string;
|
|
352
135
|
/** @internal */
|
|
353
|
-
export function prettyFormatError<ErrorType extends IError = IError>(e: ErrorType, withMessage?: boolean, boundary?: CallableFunction): string;
|
|
354
|
-
export function prettyFormatError<ErrorType extends IError = IError>(e: ErrorType, withMessage = true, boundary: CallableFunction = prettyFormatError) {
|
|
136
|
+
export function prettyFormatError<ErrorType extends IError = IError>(e: ErrorType, withMessage?: boolean, boundary?: CallableFunction | false): string;
|
|
137
|
+
export function prettyFormatError<ErrorType extends IError = IError>(e: ErrorType, withMessage = true, boundary: CallableFunction | false = prettyFormatError) {
|
|
355
138
|
if (!e || !e.stack) {
|
|
356
139
|
if (withMessage) {
|
|
357
140
|
const msg = e?.message || 'Unknown Error';
|
|
@@ -382,107 +165,201 @@ export function prettyFormatError<ErrorType extends IError = IError>(e: ErrorTyp
|
|
|
382
165
|
return prettyFormatStack(stackLines, boundary).join('\n');
|
|
383
166
|
}
|
|
384
167
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
168
|
+
class Formatter {
|
|
169
|
+
private messageEnded = false;
|
|
170
|
+
|
|
171
|
+
constructor() {
|
|
172
|
+
this.stringifyLine = this.stringifyLine.bind(this);
|
|
173
|
+
this.translateFunction = this.translateFunction.bind(this);
|
|
174
|
+
this.skipSomeFrame = this.skipSomeFrame.bind(this);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private formatFileLine(schema: string | undefined, file: string, row?: number, col?: number) {
|
|
178
|
+
let rel = file;
|
|
179
|
+
|
|
180
|
+
if (schema !== 'node:') {
|
|
181
|
+
try {
|
|
182
|
+
rel = relativePath(errorRootPath, file);
|
|
183
|
+
if (rel[0] !== '.') {
|
|
184
|
+
rel = `./${rel}`;
|
|
185
|
+
} else if (rel[1] === '.') {
|
|
186
|
+
if (file.length < rel.length) {
|
|
187
|
+
rel = file;
|
|
188
|
+
}
|
|
396
189
|
}
|
|
190
|
+
if (rel[0] === '.') {
|
|
191
|
+
schema = '';
|
|
192
|
+
}
|
|
193
|
+
} catch {
|
|
194
|
+
// if (!alert) {
|
|
195
|
+
// alert = true;
|
|
196
|
+
// console.error('pretty print failed parse line: \n\x1B[2mFormat%s\x1B[0m', e.stack);
|
|
197
|
+
// }
|
|
198
|
+
rel = file;
|
|
397
199
|
}
|
|
398
|
-
if (rel[0] === '.') {
|
|
399
|
-
schema = '';
|
|
400
|
-
}
|
|
401
|
-
} catch {
|
|
402
|
-
// if (!alert) {
|
|
403
|
-
// alert = true;
|
|
404
|
-
// console.error('pretty print failed parse line: \n\x1B[2mFormat%s\x1B[0m', e.stack);
|
|
405
|
-
// }
|
|
406
|
-
rel = file;
|
|
407
200
|
}
|
|
408
|
-
}
|
|
409
201
|
|
|
410
|
-
|
|
411
|
-
}
|
|
202
|
+
return `${schema || ''}${rel}${row ? `:${row}` : ''}${col ? `:${col}` : ''}`;
|
|
203
|
+
}
|
|
412
204
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
205
|
+
private formatFunctionName(fn?: string, as?: string) {
|
|
206
|
+
if (fn) {
|
|
207
|
+
if (as) {
|
|
208
|
+
return `${fn} [as ${as}]`;
|
|
209
|
+
}
|
|
210
|
+
return fn;
|
|
417
211
|
}
|
|
418
|
-
return
|
|
212
|
+
return '<anonymous>';
|
|
419
213
|
}
|
|
420
|
-
return '<anonymous>';
|
|
421
|
-
}
|
|
422
214
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
}
|
|
215
|
+
stringifyLine(line: IStructreStackLine) {
|
|
216
|
+
let ret: string;
|
|
217
|
+
if (line.special) {
|
|
218
|
+
return line.toString();
|
|
219
|
+
}
|
|
220
|
+
if (line.invalid) {
|
|
221
|
+
if (this.messageEnded) {
|
|
222
|
+
return red(line.toString());
|
|
223
|
+
}
|
|
224
|
+
return line.toString();
|
|
225
|
+
}
|
|
226
|
+
this.messageEnded = true;
|
|
227
|
+
const fn_name = line.func?.name;
|
|
228
|
+
|
|
229
|
+
if (!line.location?.isAbsolute || line.location.schema === 'node:') {
|
|
230
|
+
// no-path, relative path, node:
|
|
231
|
+
ret = ' at \x1B[2m';
|
|
232
|
+
if (line.func) {
|
|
233
|
+
ret += fn_name;
|
|
234
|
+
if (line.func.alias) {
|
|
235
|
+
ret += ` [${line.func.alias}]`;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
447
238
|
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
239
|
+
if (line.location?.path === '<anonymous>') {
|
|
240
|
+
} else if (line.location?.path) {
|
|
241
|
+
if (fn_name) {
|
|
242
|
+
ret += ' (';
|
|
243
|
+
}
|
|
244
|
+
ret += this.formatFileLine(line.location.schema, line.location.path, line.location.line, line.location.column);
|
|
245
|
+
if (fn_name) {
|
|
246
|
+
ret += ')';
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
ret += '\x1B[0m';
|
|
250
|
+
} else {
|
|
251
|
+
const path = line.location.path;
|
|
252
|
+
const isNodeModule = path.includes('/node_modules/');
|
|
253
|
+
const fn_alias = line.func?.alias;
|
|
254
|
+
|
|
255
|
+
const color = fn_name ? (isNodeModule ? '14;2' : '14') : '8';
|
|
256
|
+
ret = `\x1b[0m at \x1b[38;5;${color}m`;
|
|
257
|
+
if (fn_alias && fn_name && fn_name.startsWith('Object.')) {
|
|
258
|
+
ret += `${fn_alias} [export]`;
|
|
259
|
+
} else {
|
|
260
|
+
ret += this.formatFunctionName(fn_name, fn_alias);
|
|
261
|
+
}
|
|
262
|
+
ret += '\x1b[0m';
|
|
263
|
+
if (line.eval) {
|
|
264
|
+
ret += `\x1b[2m(${line.eval.funcs.filter((e) => e !== '<anonymous>').join('->')})\x1b[0m`;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (path) {
|
|
268
|
+
let color: string;
|
|
269
|
+
if (isNodeModule) {
|
|
270
|
+
color = '\x1b[38;5;237m';
|
|
271
|
+
} else {
|
|
272
|
+
color = '\x1b[38;5;2m';
|
|
273
|
+
}
|
|
274
|
+
ret += ` (${color}`;
|
|
275
|
+
const file = this.formatFileLine(line.location.schema, path, line.location.line, line.location.column);
|
|
276
|
+
const lastNmPos = file.lastIndexOf('/node_modules/');
|
|
277
|
+
if (lastNmPos >= 0) {
|
|
278
|
+
ret += file.slice(0, lastNmPos + 14);
|
|
279
|
+
|
|
280
|
+
let nextSlash = file.indexOf('/', lastNmPos + 15);
|
|
281
|
+
const scopePkg = file[lastNmPos + 14] === '@';
|
|
282
|
+
if (scopePkg) {
|
|
283
|
+
nextSlash = file.indexOf('/', nextSlash + 1);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
ret += '\x1B[0m';
|
|
287
|
+
ret += file.slice(lastNmPos + 14, nextSlash);
|
|
288
|
+
ret += color;
|
|
289
|
+
ret += file.slice(nextSlash);
|
|
290
|
+
} else {
|
|
291
|
+
ret += file;
|
|
292
|
+
}
|
|
293
|
+
ret += '\x1B[0m)';
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return ret;
|
|
454
297
|
}
|
|
455
298
|
|
|
456
|
-
|
|
457
|
-
if (
|
|
458
|
-
return
|
|
299
|
+
translateFunction(data: IStructreStackLine): IStructreStackLine {
|
|
300
|
+
if (!data.func?.name) {
|
|
301
|
+
return data;
|
|
459
302
|
}
|
|
460
|
-
if (
|
|
461
|
-
|
|
303
|
+
if (data.func.name === 'Timeout._onTimeout') {
|
|
304
|
+
data.func.name = 'setTimeout';
|
|
462
305
|
}
|
|
463
|
-
if (
|
|
464
|
-
|
|
306
|
+
if (data.func.name === 'Immediate._onImmediate') {
|
|
307
|
+
data.func.name = 'setImmediate';
|
|
465
308
|
}
|
|
466
|
-
if (
|
|
467
|
-
|
|
309
|
+
if (data.func.name === 'process.processTicksAndRejections') {
|
|
310
|
+
data.func.name = 'process.nextTick';
|
|
468
311
|
}
|
|
469
|
-
if (
|
|
470
|
-
|
|
312
|
+
if (data.func.name.startsWith('Timeout.') && data.func.alias === '_onTimeout') {
|
|
313
|
+
data.func.name = `setTimeout->${data.func.name.slice(8)}`;
|
|
314
|
+
data.func.alias = undefined;
|
|
471
315
|
}
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
316
|
+
if (data.func.name.startsWith('async Promise.all')) {
|
|
317
|
+
data.func.name = `Promise.all()`;
|
|
318
|
+
data.func.alias = data.location?.path;
|
|
319
|
+
data.location = undefined;
|
|
476
320
|
}
|
|
321
|
+
return data;
|
|
477
322
|
}
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
*
|
|
326
|
+
*/
|
|
327
|
+
skipSomeFrame({ func, location }: IStructreStackLine): boolean {
|
|
328
|
+
if (!location?.path) {
|
|
329
|
+
return true;
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
if (location.schema === 'node:') {
|
|
333
|
+
if (location.path.startsWith('internal/timers')) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
336
|
+
if (location.path === 'internal/modules/cjs/loader') {
|
|
337
|
+
return false;
|
|
338
|
+
}
|
|
339
|
+
if (location.path === 'internal/modules/esm/loader') {
|
|
340
|
+
return false;
|
|
341
|
+
}
|
|
342
|
+
if (location.path === 'internal/modules/run_main') {
|
|
343
|
+
return false;
|
|
344
|
+
}
|
|
345
|
+
if (location.path === 'internal/modules/esm/module_job') {
|
|
346
|
+
return false;
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (!location.path.includes('/')) {
|
|
350
|
+
if (location.path.startsWith('_stream_')) {
|
|
351
|
+
return false;
|
|
352
|
+
}
|
|
482
353
|
}
|
|
483
|
-
if (
|
|
484
|
-
|
|
354
|
+
if (location.path === '<anonymous>') {
|
|
355
|
+
// new Promise ('<anonymous>')
|
|
356
|
+
if (func?.name === 'new Promise') {
|
|
357
|
+
return false;
|
|
358
|
+
}
|
|
359
|
+
if (func?.name === 'new Function') {
|
|
360
|
+
return false;
|
|
361
|
+
}
|
|
485
362
|
}
|
|
363
|
+
return true;
|
|
486
364
|
}
|
|
487
|
-
return true;
|
|
488
365
|
}
|