@jsenv/test 3.3.16 → 3.3.18
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/dist/js/execute_using_dynamic_import.js +2 -2
- package/dist/js/v8_coverage.js +535 -2
- package/dist/jsenv_test.js +35 -61
- package/dist/node_child_process_controlled.mjs +1 -1
- package/dist/node_worker_thread_controlled.mjs +1 -1
- package/package.json +9 -9
- package/src/execution/run.js +1 -2
- package/src/runtime_node/execute_using_dynamic_import.js +1 -2
- package/src/runtime_node/node_child_process_controlled.mjs +1 -2
- package/src/runtime_node/node_worker_thread_controlled.mjs +1 -2
- package/dist/js/exception.js +0 -932
- package/src/execution/exception.js +0 -231
|
@@ -1,231 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Exception are objects used to wrap a value that is thrown
|
|
3
|
-
* Usually they wrap error but the value can be anything as
|
|
4
|
-
* throw "toto" can be used in JS
|
|
5
|
-
*
|
|
6
|
-
* - provide a common API to interact with value that can be thrown
|
|
7
|
-
* - enrich usual errors with a bit more information (line, column)
|
|
8
|
-
* - normalize error properties
|
|
9
|
-
* - exception.stackTrace: only the stack trace as string (no error.name or error.message)
|
|
10
|
-
* - error.stack: error.name + error.message + error.stackTrace
|
|
11
|
-
*
|
|
12
|
-
* It is used mostly internally by jsenv but can also be found
|
|
13
|
-
* value returned by "executeTestPlan" public export (for failed executions)
|
|
14
|
-
* and value returned by "execute" public export (when execution fails)
|
|
15
|
-
*
|
|
16
|
-
* This file is responsible to wrap error hapenning in Node.js runtime
|
|
17
|
-
* The browser part can be found in "supervisor.js"
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
// https://github.com/marvinhagemeister/errorstacks/tree/main
|
|
21
|
-
// https://cdn.jsdelivr.net/npm/errorstacks@latest/dist/esm/index.mjs
|
|
22
|
-
import { URL_META } from "@jsenv/url-meta";
|
|
23
|
-
import { parseStackTrace } from "errorstacks";
|
|
24
|
-
|
|
25
|
-
const isDev = process.execArgv.includes("--conditions=development");
|
|
26
|
-
const jsenvCoreDirectoryUrl = new URL("../../../../../", import.meta.url);
|
|
27
|
-
|
|
28
|
-
export const createException = (reason, { rootDirectoryUrl } = {}) => {
|
|
29
|
-
const exception = {
|
|
30
|
-
isException: true,
|
|
31
|
-
isError: false,
|
|
32
|
-
name: "",
|
|
33
|
-
message: "",
|
|
34
|
-
stack: "",
|
|
35
|
-
stackTrace: "",
|
|
36
|
-
stackFrames: undefined,
|
|
37
|
-
site: null,
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
if (reason === undefined) {
|
|
41
|
-
exception.message = "undefined";
|
|
42
|
-
return exception;
|
|
43
|
-
}
|
|
44
|
-
if (reason === null) {
|
|
45
|
-
exception.message = "null";
|
|
46
|
-
return exception;
|
|
47
|
-
}
|
|
48
|
-
if (typeof reason === "string") {
|
|
49
|
-
exception.message = reason;
|
|
50
|
-
return exception;
|
|
51
|
-
}
|
|
52
|
-
if (typeof reason !== "object") {
|
|
53
|
-
exception.message = JSON.stringify(reason);
|
|
54
|
-
return exception;
|
|
55
|
-
}
|
|
56
|
-
if (reason.stackFrames === undefined && "stack" in reason) {
|
|
57
|
-
let stackFrames;
|
|
58
|
-
|
|
59
|
-
const { prepareStackTrace } = Error;
|
|
60
|
-
Error.prepareStackTrace = (e, callSites) => {
|
|
61
|
-
Error.prepareStackTrace = prepareStackTrace;
|
|
62
|
-
|
|
63
|
-
stackFrames = [];
|
|
64
|
-
for (const callSite of callSites) {
|
|
65
|
-
const stackFrame = {
|
|
66
|
-
raw: ` at ${String(callSite)}`,
|
|
67
|
-
url: callSite.getFileName() || callSite.getScriptNameOrSourceURL(),
|
|
68
|
-
line: callSite.getLineNumber(),
|
|
69
|
-
column: callSite.getColumnNumber(),
|
|
70
|
-
functionName: callSite.getFunctionName(),
|
|
71
|
-
isNative: callSite.isNative(),
|
|
72
|
-
isEval: callSite.isEval(),
|
|
73
|
-
isConstructor: callSite.isConstructor(),
|
|
74
|
-
isAsync: callSite.isAsync(),
|
|
75
|
-
evalSite: null,
|
|
76
|
-
};
|
|
77
|
-
if (stackFrame.isEval) {
|
|
78
|
-
const evalOrigin = stackFrame.getEvalOrigin();
|
|
79
|
-
if (evalOrigin) {
|
|
80
|
-
stackFrame.evalSite = getPropertiesFromEvalOrigin(evalOrigin);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
stackFrames.push(stackFrame);
|
|
84
|
-
}
|
|
85
|
-
return "";
|
|
86
|
-
};
|
|
87
|
-
exception.stack = reason.stack;
|
|
88
|
-
if (stackFrames === undefined) {
|
|
89
|
-
// Error.prepareStackTrace not trigerred
|
|
90
|
-
// - reason is not an error
|
|
91
|
-
// - reason.stack already get
|
|
92
|
-
Error.prepareStackTrace = prepareStackTrace;
|
|
93
|
-
|
|
94
|
-
const calls = parseStackTrace(reason.stack);
|
|
95
|
-
stackFrames = [];
|
|
96
|
-
for (const call of calls) {
|
|
97
|
-
if (call.fileName === "") {
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
stackFrames.push({
|
|
101
|
-
raw: call.raw,
|
|
102
|
-
functionName: call.name,
|
|
103
|
-
url: call.fileName,
|
|
104
|
-
line: call.line,
|
|
105
|
-
column: call.column,
|
|
106
|
-
native: call.type === "native",
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
const stackFramesNonNative = [];
|
|
112
|
-
for (const stackFrame of stackFrames) {
|
|
113
|
-
if (!stackFrame.url) {
|
|
114
|
-
continue;
|
|
115
|
-
}
|
|
116
|
-
if (stackFrame.url.startsWith("node:")) {
|
|
117
|
-
stackFrame.native = "node";
|
|
118
|
-
continue;
|
|
119
|
-
}
|
|
120
|
-
if (stackFrame.url.startsWith("file:")) {
|
|
121
|
-
if (rootDirectoryUrl && stackFrame.url.startsWith(rootDirectoryUrl)) {
|
|
122
|
-
stackFramesNonNative.push(stackFrame);
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
if (isDev) {
|
|
127
|
-
// while developing jsenv itself we want to exclude any
|
|
128
|
-
// - src/*
|
|
129
|
-
// - packages/**/src/
|
|
130
|
-
// for the users of jsenv it's easier, we want to exclude
|
|
131
|
-
// - **/node_modules/@jsenv/**
|
|
132
|
-
if (
|
|
133
|
-
URL_META.matches(stackFrame.url, {
|
|
134
|
-
[`${jsenvCoreDirectoryUrl}src/`]: true,
|
|
135
|
-
[`${jsenvCoreDirectoryUrl}packages/**/src/`]: true,
|
|
136
|
-
})
|
|
137
|
-
) {
|
|
138
|
-
stackFrame.native = "jsenv";
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
} else if (
|
|
142
|
-
URL_META.matches(stackFrame.url, {
|
|
143
|
-
"file:///**/node_modules/@jsenv/core/": true,
|
|
144
|
-
})
|
|
145
|
-
) {
|
|
146
|
-
stackFrame.native = "jsenv";
|
|
147
|
-
continue;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
stackFramesNonNative.push(stackFrame);
|
|
151
|
-
}
|
|
152
|
-
if (stackFramesNonNative.length) {
|
|
153
|
-
stackFrames = stackFramesNonNative;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
reason.stackFrames = stackFrames;
|
|
157
|
-
|
|
158
|
-
let stackTrace = "";
|
|
159
|
-
for (const stackFrame of stackFrames) {
|
|
160
|
-
if (stackTrace) stackTrace += "\n";
|
|
161
|
-
stackTrace += stackFrame.raw;
|
|
162
|
-
}
|
|
163
|
-
reason.stackTrace = stackTrace;
|
|
164
|
-
let stack = "";
|
|
165
|
-
const name = getErrorName(reason);
|
|
166
|
-
const message = reason.message || "";
|
|
167
|
-
stack += `${name}: ${message}`;
|
|
168
|
-
if (stackTrace) {
|
|
169
|
-
stack += `\n${stackTrace}`;
|
|
170
|
-
}
|
|
171
|
-
reason.stack = stack;
|
|
172
|
-
|
|
173
|
-
const [firstCallFrame] = stackFrames;
|
|
174
|
-
if (firstCallFrame && (!reason.site || !reason.site.isInline)) {
|
|
175
|
-
reason.site = firstCallFrame.url
|
|
176
|
-
? {
|
|
177
|
-
url: firstCallFrame.url,
|
|
178
|
-
line: firstCallFrame.line,
|
|
179
|
-
column: firstCallFrame.column,
|
|
180
|
-
}
|
|
181
|
-
: firstCallFrame.evalSite;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
// getOwnPropertyNames to catch non enumerable properties on reason
|
|
185
|
-
// (happens mostly when reason is instanceof Error)
|
|
186
|
-
// like .stack, .message
|
|
187
|
-
// some properties are even on the prototype like .name
|
|
188
|
-
for (const ownPropertyName of Object.getOwnPropertyNames(reason)) {
|
|
189
|
-
exception[ownPropertyName] = reason[ownPropertyName];
|
|
190
|
-
}
|
|
191
|
-
const isError = reason instanceof Error;
|
|
192
|
-
exception.isError = isError;
|
|
193
|
-
if (isError) {
|
|
194
|
-
// getOwnPropertyNames is not enough to copy .name and .message
|
|
195
|
-
// on error instances
|
|
196
|
-
exception.name = getErrorName(reason);
|
|
197
|
-
exception.message = reason.message;
|
|
198
|
-
}
|
|
199
|
-
return exception;
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
const getErrorName = (value) => {
|
|
203
|
-
const { constructor } = value;
|
|
204
|
-
if (constructor) {
|
|
205
|
-
if (constructor.name !== "Object") {
|
|
206
|
-
return constructor.name;
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
return value.name || "Error";
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
const getPropertiesFromEvalOrigin = (origin) => {
|
|
213
|
-
// Most eval() calls are in this format
|
|
214
|
-
const topLevelEvalMatch = /^eval at [^(]+ \(.+:\d+:\d+\)$/.exec(origin);
|
|
215
|
-
if (topLevelEvalMatch) {
|
|
216
|
-
const source = topLevelEvalMatch[2];
|
|
217
|
-
const line = Number(topLevelEvalMatch[3]);
|
|
218
|
-
const column = topLevelEvalMatch[4] - 1;
|
|
219
|
-
return {
|
|
220
|
-
url: source,
|
|
221
|
-
line,
|
|
222
|
-
column,
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
// Parse nested eval() calls using recursion
|
|
226
|
-
const nestedEvalMatch = /^eval at [^(]+ \(.+\)$/.exec(origin);
|
|
227
|
-
if (nestedEvalMatch) {
|
|
228
|
-
return getPropertiesFromEvalOrigin(nestedEvalMatch[2]);
|
|
229
|
-
}
|
|
230
|
-
return null;
|
|
231
|
-
};
|