diff --git a/src/jsc/bindings/FormatStackTraceForJS.cpp b/src/jsc/bindings/FormatStackTraceForJS.cpp index d622679f31aa..6c2deb376f1e 100644 --- a/src/jsc/bindings/FormatStackTraceForJS.cpp +++ b/src/jsc/bindings/FormatStackTraceForJS.cpp @@ -668,11 +668,11 @@ JSC_DEFINE_HOST_FUNCTION(errorConstructorFuncAppendStackTrace, (JSC::JSGlobalObj return {}; } - if (!destination->stackTrace()) { + if (!destination->stackTrace() && globalObject->stackTraceLimit()) { destination->captureStackTrace(vm, globalObject, 1); } - if (source->stackTrace()) { + if (source->stackTrace() && destination->stackTrace()) { destination->stackTrace()->appendVector(*source->stackTrace()); source->stackTrace()->clear(); } diff --git a/test/js/node/v8/capture-stack-trace.test.js b/test/js/node/v8/capture-stack-trace.test.js index 6cd46a1ad90a..c986a4fe48e3 100644 --- a/test/js/node/v8/capture-stack-trace.test.js +++ b/test/js/node/v8/capture-stack-trace.test.js @@ -1121,3 +1121,28 @@ test("lazy error-info materialization does not store an empty stack value when t }); expect(exitCode).toBe(0); }); + +test("Error.appendStackTrace does not abort when stackTraceLimit is not a number", async () => { + const src = ` + Error.stackTraceLimit = undefined; + const a = new Error(); + const b = new Error(); + Error.appendStackTrace(a, b); + + Error.stackTraceLimit = 10; + const c = new Error(); + delete Error.stackTraceLimit; + const d = new Error(); + Error.appendStackTrace(c, d); + + process.stdout.write("ok"); + `; + await using proc = Bun.spawn({ + cmd: [bunExe(), "-e", src], + env: bunEnv, + stderr: "pipe", + }); + const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]); + expect({ stdout, stderr, signalCode: proc.signalCode }).toEqual({ stdout: "ok", stderr: "", signalCode: null }); + expect(exitCode).toBe(0); +});