mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
### What does this PR do? Enables async stack traces ### How did you verify your code works? Added tests --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
153 lines
4.0 KiB
TypeScript
153 lines
4.0 KiB
TypeScript
import { $ } from "bun";
|
|
import { expect, test } from "bun:test";
|
|
import "harness";
|
|
import { bunEnv, bunExe, normalizeBunSnapshot } from "harness";
|
|
import { join } from "node:path";
|
|
|
|
test("name property is used for function calls in Error.stack", () => {
|
|
function WRONG() {
|
|
return new Error().stack;
|
|
}
|
|
expect(WRONG()).not.toContain("at RIGHT");
|
|
expect(WRONG()).toContain("at WRONG");
|
|
Object.defineProperty(WRONG, "name", { value: "RIGHT" });
|
|
expect(WRONG()).not.toContain("at WRONG");
|
|
expect(WRONG()).toContain("at RIGHT");
|
|
});
|
|
|
|
test("name property is used for function calls in Bun.inspect", () => {
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
function WRONG() {
|
|
try {
|
|
throw new Error();
|
|
} catch (e) {
|
|
return Bun.inspect(e);
|
|
}
|
|
}
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
expect(WRONG()).not.toContain("at RIGHT");
|
|
expect(WRONG()).toContain("at WRONG");
|
|
Object.defineProperty(WRONG, "name", { value: "RIGHT" });
|
|
expect(WRONG()).not.toContain("at WRONG");
|
|
expect(WRONG()).toContain("at RIGHT");
|
|
});
|
|
|
|
test.todo("name property is used for function calls in Bun.inspect with bound object", () => {
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
let WRONG = function WRONG() {
|
|
try {
|
|
throw new Error();
|
|
} catch (e) {
|
|
return Bun.inspect(e);
|
|
}
|
|
};
|
|
WRONG = WRONG.bind({});
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
// ** whitespace **
|
|
expect(WRONG()).not.toContain("at RIGHT");
|
|
expect(WRONG()).toContain("at WRONG");
|
|
Object.defineProperty(WRONG, "name", { value: "RIGHT", writable: true, configurable: true });
|
|
console.log(WRONG());
|
|
expect(WRONG()).not.toContain("at WRONG");
|
|
expect(WRONG()).toContain("at RIGHT");
|
|
});
|
|
|
|
test("err.line and err.column are set", () => {
|
|
expect([join(import.meta.dir, "err-stack-fixture.js")]).toRun(
|
|
JSON.stringify(
|
|
{
|
|
line: 3,
|
|
column: 17,
|
|
originalLine: 1,
|
|
originalColumn: 18,
|
|
},
|
|
null,
|
|
2,
|
|
) + "\n",
|
|
);
|
|
});
|
|
|
|
test("throwing inside an error suppresses the error and prints the stack", async () => {
|
|
$.throws(false);
|
|
$.env(bunEnv);
|
|
const result = await $`${bunExe()} run ${join(import.meta.dir, "err-custom-fixture.js")}`;
|
|
|
|
const { stderr, exitCode } = result;
|
|
|
|
expect(stderr.toString().trim().split("\n").slice(0, -1).join("\n").trim()).toMatchInlineSnapshot(`
|
|
"error: My custom error message
|
|
{
|
|
message: "My custom error message",
|
|
name: [Getter],
|
|
line: 42,
|
|
sourceURL: "http://example.com/test.js",
|
|
}
|
|
at http://example.com/test.js:42"
|
|
`);
|
|
expect(exitCode).toBe(1);
|
|
});
|
|
|
|
test("throwing inside an error suppresses the error and continues printing properties on the object", async () => {
|
|
$.throws(false);
|
|
$.env(bunEnv);
|
|
const result = await $`${bunExe()} run ${join(import.meta.dir, "err-fd-fixture.js")}`;
|
|
|
|
const { stderr, exitCode } = result;
|
|
|
|
expect(stderr.toString().trim()).toStartWith(`ENOENT: no such file or directory, open 'this-file-path-is-bad'
|
|
path: "this-file-path-is-bad",
|
|
syscall: "open",
|
|
errno: -2,
|
|
code: "ENOENT"
|
|
`);
|
|
expect(exitCode).toBe(1);
|
|
});
|
|
|
|
test("Async functions frame should be included in stack trace", async () => {
|
|
async function foo() {
|
|
return await bar();
|
|
}
|
|
async function bar() {
|
|
return await baz();
|
|
}
|
|
async function baz() {
|
|
await 1;
|
|
return await qux();
|
|
}
|
|
async function qux() {
|
|
return new Error("error from qux");
|
|
}
|
|
|
|
const error = await foo();
|
|
|
|
console.log(error.stack);
|
|
|
|
expect(normalizeBunSnapshot(error.stack!)).toMatchInlineSnapshot(`
|
|
"Error: error from qux
|
|
at qux (file:NN:NN)
|
|
at baz (file:NN:NN)
|
|
at async bar (file:NN:NN)
|
|
at async foo (file:NN:NN)
|
|
at async <anonymous> (file:NN:NN)"
|
|
`);
|
|
});
|