Skip to content

Commit

Permalink
Add pathFilter option (#33)
Browse files Browse the repository at this point in the history
Co-authored-by: Sindre Sorhus <[email protected]>
  • Loading branch information
broguinn and sindresorhus committed Mar 21, 2023
1 parent 5c7f014 commit fa2b9c3
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 2 deletions.
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

0 comments on commit fa2b9c3

Please sign in to comment.