-
Notifications
You must be signed in to change notification settings - Fork 1.4k
/
Copy pathserialize-error.js
98 lines (82 loc) · 2.62 KB
/
serialize-error.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import path from 'node:path';
import {pathToFileURL} from 'node:url';
import {isNativeError} from 'node:util/types';
import concordance from 'concordance';
import StackUtils from 'stack-utils';
import {AssertionError} from './assert.js';
import concordanceOptions from './concordance-options.js';
function isAvaAssertionError(source) {
return source instanceof AssertionError;
}
function normalizeFile(file, ...base) {
return file.startsWith('file://') ? file : pathToFileURL(path.resolve(...base, file)).toString();
}
const stackUtils = new StackUtils();
function extractSource(stack, testFile) {
if (!stack || !testFile) {
return null;
}
testFile = normalizeFile(testFile);
for (const line of stack.split('\n')) {
const callSite = stackUtils.parseLine(line);
if (callSite && normalizeFile(callSite.file) === testFile) {
return {
isDependency: false,
isWithinProject: true,
file: testFile,
line: callSite.line,
};
}
}
return null;
}
const workerErrors = new WeakSet();
export function tagWorkerError(error) {
// Track worker errors, which aren't native due to https://github.com/nodejs/node/issues/48716.
// Still include the check for isNativeError() in case the issue is fixed in the future.
if (isNativeError(error) || error instanceof Error) {
workerErrors.add(error);
}
return error;
}
const isWorkerError = error => workerErrors.has(error);
export default function serializeError(error, {testFile = null} = {}) {
if (!isNativeError(error) && !isWorkerError(error)) {
return {
type: 'unknown',
originalError: error, // Note that the main process receives a structured clone.
formattedError: concordance.formatDescriptor(concordance.describe(error, concordanceOptions), concordanceOptions),
};
}
const {message, name, stack} = error;
const base = {
message,
name,
originalError: error, // Note that the main process receives a structured clone.
stack,
};
if (!isAvaAssertionError(error)) {
if (name === 'AggregateError') {
return {
...base,
type: 'aggregate',
errors: error.errors.map(error => serializeError(error, {testFile})),
};
}
return {
...base,
type: 'native',
source: extractSource(error.stack, testFile),
};
}
return {
...base,
type: 'ava',
assertion: error.assertion,
improperUsage: error.improperUsage,
formattedCause: error.cause ? concordance.formatDescriptor(concordance.describe(error.cause, concordanceOptions), concordanceOptions) : null,
formattedDetails: error.formattedDetails,
source: extractSource(error.assertionStack, testFile),
stack: isNativeError(error.cause) ? error.cause.stack : error.assertionStack,
};
}