Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creates an optional callback to check for other paths to omit #33

Merged
merged 12 commits into from Mar 21, 2023
23 changes: 23 additions & 0 deletions index.d.ts
Expand Up @@ -16,6 +16,29 @@ export type Options = {
`/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15` → `unicorn.js:2:15`
*/
readonly basePath?: string;

/**
Remove the stack lines where the given function returns `false`. The function receives the path part of the stack line.

@example
```
import cleanStack from 'clean-stack';

const error = new Error('Missing unicorn');

console.log(cleanStack(error.stack));
// Error: Missing unicorn
// at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15)
// at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/omit-me.js:1:16)

const pathFilter = path => !/omit-me/.test(path);

console.log(cleanStack(error.stack, {pathFilter}));
// Error: Missing unicorn
// at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15)
```
*/
readonly pathFilter?: (path: string) => boolean;
};

/**
Expand Down
6 changes: 4 additions & 2 deletions index.js
Expand Up @@ -4,7 +4,7 @@ import getHomeDirectory from '#home-directory';
const extractPathRegex = /\s+at.*[(\s](.*)\)?/;
const pathRegex = /^(?:(?:(?:node|node:[\w/]+|(?:(?:node:)?internal\/[\w/]*|.*node_modules\/(?:babel-polyfill|pirates)\/.*)?\w+)(?:\.js)?:\d+:\d+)|native)/;

export default function cleanStack(stack, {pretty = false, basePath} = {}) {
export default function cleanStack(stack, {pretty = false, basePath, pathFilter} = {}) {
const basePathRegex = basePath && new RegExp(`(file://)?${escapeStringRegexp(basePath.replace(/\\/g, '/'))}/?`, 'g');
const homeDirectory = pretty ? getHomeDirectory() : '';

Expand Down Expand Up @@ -32,7 +32,9 @@ export default function cleanStack(stack, {pretty = false, basePath} = {}) {
return false;
}

return !pathRegex.test(match);
return pathFilter
? !pathRegex.test(match) && pathFilter(match)
: !pathRegex.test(match);
})
.filter(line => line.trim() !== '')
.map(line => {
Expand Down
23 changes: 23 additions & 0 deletions readme.md
Expand Up @@ -73,6 +73,29 @@ Example with `'/Users/sindresorhus/dev/clean-stack'` as `basePath`:

`/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15` → `unicorn.js:2:15`

##### pathFilter

Type: `(path: string) => boolean`

Remove the stack lines where the given function returns `false`. The function receives the path part of the stack line.

```js
import cleanStack from 'clean-stack';

const error = new Error('Missing unicorn');

console.log(cleanStack(error.stack));
// Error: Missing unicorn
// at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15)
// at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/omit-me.js:1:16)

const pathFilter = path => !/omit-me/.test(path);

console.log(cleanStack(error.stack, {pathFilter}));
// Error: Missing unicorn
// at Object.<anonymous> (/Users/sindresorhus/dev/clean-stack/unicorn.js:2:15)
```

## Related

- [extract-stack](https://github.com/sindresorhus/extract-stack) - Extract the actual stack of an error
Expand Down
34 changes: 34 additions & 0 deletions test.js
Expand Up @@ -218,6 +218,40 @@ test('`basePath` option should support file URLs', t => {
t.is(cleanStack(stack, {basePath, pretty: true}), expected);
});

test('`pathFilter` option allows for excluding custom lines if the callback returns true', t => {
const pathFilter = path => !/home-directory/.test(path);

const pre = `Error: foo
at Test.fn (/Users/sindresorhus/dev/clean-stack/test.js:6:15)`;

const stack = `${pre}\n
at getHomeDirectory (/Users/sindresorhus/dev/clean-stack/home-directory.js:3:32)
at MySocket.emit (node:events:365:28)
at MySocket.emit (node:fs/promises:363:28)
at handleMessage (internal/child_process.js:695:10)
at Pipe.channel.onread (internal/child_process.js:440:11)
at process.emit (events.js:172:7)`;

t.is(cleanStack(stack, {pathFilter}), pre);
});

test('`pathFilter` option keeps custom lines if the callback returns false', t => {
const pathFilterCallback = () => true;

const pre = `Error: foo
at Test.fn (/Users/sindresorhus/dev/clean-stack/test.js:6:15)
at getHomeDirectory (/Users/sindresorhus/dev/clean-stack/home-directory.js:3:32)`;

const stack = `${pre}\n
at MySocket.emit (node:events:365:28)
at MySocket.emit (node:fs/promises:363:28)
at handleMessage (internal/child_process.js:695:10)
at Pipe.channel.onread (internal/child_process.js:440:11)
at process.emit (events.js:172:7)`;

t.is(cleanStack(stack, {pathFilterCallback}), pre);
});

test('new stack format on Node.js 15 and later', t => {
const stack = `Error
at B (/home/fengkx/projects/test/stack.js:5:19)
Expand Down