Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 0 additions & 5 deletions .babelrc

This file was deleted.

1 change: 0 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ jobs:
uses: actions/setup-node@v6
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

Comment thread
niemyjski marked this conversation as resolved.
- run: npm ci

Expand Down
3 changes: 1 addition & 2 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
__tests__/
.babelrc
.travis.yml
.github/
17 changes: 9 additions & 8 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,15 @@ certain properties can be retrieved with it as noted in the API docs below.

## Long stack traces

stack-trace works great with [long-stack-traces][], when parsing an `err.stack`
that has crossed the event loop boundary, a `CallSite` object returning
`'----------------------------------------'` for `getFileName()` is created.
All other methods of the event loop boundary call site return `null`.
When parsing an `err.stack` that has crossed the event loop boundary, a
`CallSite` object is created whose `getFileName()` returns the full dashed
separator line from the stack, including any leading whitespace such as
indentation. All other methods of the event loop boundary call site return
`null`.
Comment on lines +44 to +45

[long-stack-traces]: https://github.com/tlrobinson/long-stack-traces
Historically this behavior was often observed together with
[long-stack-traces](https://github.com/tlrobinson/long-stack-traces), but that package is unmaintained. This module does not depend on it and still supports parsing dashed event-loop boundary markers when
they are present in the stack string.

## API

Expand Down Expand Up @@ -75,7 +78,7 @@ is sometimes a little different, but still useful.

### CallSite

The official v8 CallSite object API can be found [here](https://v8.dev/docs/stack-trace-api#customizing-stack-traces). A quick
The official v8 CallSite object API can be found in the [V8 stack trace API docs](https://v8.dev/docs/stack-trace-api#customizing-stack-traces). A quick
excerpt:

> A CallSite object defines the following methods:
Expand All @@ -94,8 +97,6 @@ excerpt:
> * **isNative**: is this call in native V8 code?
> * **isConstructor**: is this a constructor call?

[v8stackapi]: https://v8.dev/docs/stack-trace-api

## License

stack-trace is licensed under the MIT license.
18 changes: 9 additions & 9 deletions __tests__/get-test.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { get } from "../index.js";

describe("get", () => {
test("basic", () => {
it("basic", () => {
(function testBasic() {
var trace = get();

//expect(trace[0].getFunction()).toBe(testBasic);
expect(trace[0].getFunctionName()).toBe('testBasic');
expect(trace[0].getFileName()).toBe(__filename);
assert.strictEqual(trace[0].getFunctionName(), 'testBasic');
assert.strictEqual(trace[0].getFileName(), import.meta.url);
})();
});

test("wrapper", () => {
it("wrapper", () => {
(function testWrapper() {
(function testBelowFn() {
var trace = get(testBelowFn);
//expect(trace[0].getFunction()).toBe(testWrapper);
expect(trace[0].getFunctionName()).toBe('testWrapper');
assert.strictEqual(trace[0].getFunctionName(), 'testWrapper');
})();
})();
});

test("deep", () => {
it("deep", () => {
(function deep1() {
(function deep2() {
(function deep3() {
Expand All @@ -35,7 +35,7 @@ describe("get", () => {
(function deep10() {
const trace = get();
const hasFirstCallSite = trace.some(callSite => callSite.getFunctionName() === 'deep1');
expect(hasFirstCallSite).toBe(true);
assert.strictEqual(hasFirstCallSite, true);
})();
})();
})();
Expand Down
44 changes: 29 additions & 15 deletions __tests__/long-stack-trace-test.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,36 @@
import { describe, it } from 'node:test';
import assert from 'node:assert/strict';
import { parse } from "../index.js";
const _ = require('long-stack-traces');

// Previously this test used the unmaintained 'long-stack-traces' package
// (https://github.com/tlrobinson/long-stack-traces) which monkeypatched
// async APIs to insert dashed separator lines into Error#stack across event
// loop boundaries. That package (and its suggested replacement 'longjohn')
// are both unmaintained and incompatible with modern Node.js ESM.
//
// The parser behavior is preserved: parse() detects lines matching /^\s*[-]{4,}$/
// and returns a CallSite with getFileName() === the dashed line. This test
// validates that behavior deterministically using a synthetic stack string.

describe("long stack trace", () => {
test("basic", (done) => {
function badFn() {
var err = new Error('oh no');
var trace = parse(err);
it("parses event loop boundary markers", () => {
const err = {
stack:
'Error: oh no\n' +
' at badFn (/path/to/file.js:10:5)\n' +
' ----------------------------------------\n' +
' at setTimeout\n' +
' at Object.<anonymous> (/path/to/file.js:20:3)'
};

const trace = parse(err);

for (var i in trace) {
var filename = trace[i].getFileName();
if (typeof filename === 'string' && filename.match(/-----/)) {
done();
return;
}
}
expect.fail();
}
const boundary = trace.find((site) => {
const fileName = site.getFileName();
return typeof fileName === 'string' && fileName.match(/-----/);
});

setTimeout(badFn, 10);
assert.notStrictEqual(boundary, undefined);
assert.match(boundary.getFileName(), /-----/);
Comment on lines +33 to +34
});
});
Loading