UNPKG

2.36 kBJavaScriptView Raw
1'use strict';
2const StackUtils = require('stack-utils');
3const cleanStack = require('clean-stack');
4const debug = require('debug')('ava');
5
6// Ignore unimportant stack trace lines
7let ignoreStackLines = [];
8
9const avaInternals = /\/ava\/(?:lib\/|lib\/worker\/)?[\w-]+\.js:\d+:\d+\)?$/;
10const avaDependencies = /\/node_modules\/(?:append-transform|bluebird|empower-core|nyc|require-precompiled|(?:ava\/node_modules\/)?(?:babel-runtime|core-js))\//;
11const stackFrameLine = /^.+( \(.+:\d+:\d+\)|:\d+:\d+)$/;
12
13if (!debug.enabled) {
14 ignoreStackLines = StackUtils.nodeInternals();
15 ignoreStackLines.push(avaInternals);
16 ignoreStackLines.push(avaDependencies);
17}
18
19const stackUtils = new StackUtils({internals: ignoreStackLines});
20
21function extractFrames(stack) {
22 return stack
23 .split('\n')
24 .map(line => line.trim())
25 .filter(line => stackFrameLine.test(line))
26 .join('\n');
27}
28
29/*
30 * Given a string value of the format generated for the `stack` property of a
31 * V8 error object, return a string that contains only stack frame information
32 * for frames that have relevance to the consumer.
33 *
34 * For example, given the following string value:
35 *
36 * ```
37 * Error
38 * at inner (/home/ava/ex.js:7:12)
39 * at /home/ava/ex.js:12:5
40 * at outer (/home/ava/ex.js:13:4)
41 * at Object.<anonymous> (/home/ava/ex.js:14:3)
42 * at Module._compile (module.js:570:32)
43 * at Object.Module._extensions..js (module.js:579:10)
44 * at Module.load (module.js:487:32)
45 * at tryModuleLoad (module.js:446:12)
46 * at Function.Module._load (module.js:438:3)
47 * at Module.runMain (module.js:604:10)
48 * ```
49 *
50 * ...this function returns the following string value:
51 *
52 * ```
53 * inner (/home/ava/ex.js:7:12)
54 * /home/ava/ex.js:12:5
55 * outer (/home/ava/ex.js:13:4)
56 * Object.<anonymous> (/home/ava/ex.js:14:3)
57 * ```
58 */
59module.exports = stack => {
60 if (!stack) {
61 return '';
62 }
63
64 stack = extractFrames(stack);
65 // Workaround for https://github.com/tapjs/stack-utils/issues/14
66 // TODO: fix it in `stack-utils`
67 stack = cleanStack(stack);
68
69 return stackUtils.clean(stack)
70 // Remove the trailing newline inserted by the `stack-utils` module
71 .trim()
72 // Remove remaining file:// prefixes, inserted by `esm`, that are not
73 // cleaned up by `stack-utils`
74 .split('\n').map(line => line.replace(/\(file:\/\/([^/].+:\d+:\d+)\)$/, '($1)')).join('\n');
75};