From 3b986daed3f5d91162477bda616b4df1fe86c9c8 Mon Sep 17 00:00:00 2001
From: Babel Bot <30521560+liuxingbaoyu@users.noreply.github.com>
Date: Thu, 21 Dec 2023 21:58:23 +0800
Subject: [PATCH 1/2] fix
---
.../src/errors/rewrite-stack-trace.ts | 103 ++++++++++++------
packages/babel-core/test/errors-stacks.js | 54 ++++++++-
2 files changed, 116 insertions(+), 41 deletions(-)
diff --git a/packages/babel-core/src/errors/rewrite-stack-trace.ts b/packages/babel-core/src/errors/rewrite-stack-trace.ts
index 20388e9103ce..01b9a588a1dd 100644
--- a/packages/babel-core/src/errors/rewrite-stack-trace.ts
+++ b/packages/babel-core/src/errors/rewrite-stack-trace.ts
@@ -94,9 +94,34 @@ export function beginHiddenCallStack(
if (!SUPPORTED) return fn;
return Object.defineProperty(
- function (...args: A) {
+ function (...args: A): R {
setupPrepareStackTrace();
- return fn(...args);
+ let isAsync = false;
+ try {
+ const ret = fn(...args);
+ // @ts-expect-error check if it's a promise
+ if (typeof ret?.then !== "function") return ret;
+
+ isAsync = true;
+ return (
+ ret
+ // @ts-expect-error checked above
+ .catch(function (err) {
+ err.stack;
+ resetPrepareStackTrace();
+ throw err;
+ })
+ .then(function (val: unknown) {
+ resetPrepareStackTrace();
+ return val;
+ })
+ );
+ } catch (err) {
+ err.stack;
+ throw err;
+ } finally {
+ if (!isAsync) resetPrepareStackTrace();
+ }
},
"name",
{ value: STOP_HIDING },
@@ -117,12 +142,43 @@ export function endHiddenCallStack(
);
}
-function setupPrepareStackTrace() {
- // @ts-expect-error This function is a singleton
- // eslint-disable-next-line no-func-assign
- setupPrepareStackTrace = () => {};
+let originalPrepareStackTrace: (err: Error, trace: CallSite[]) => string;
+let originalMaxStackTraceLimit: number;
+
+function stackTraceRewriter(err: Error, trace: CallSite[]) {
+ let newTrace = [];
+
+ const isExpected = expectedErrors.has(err);
+ let status: "showing" | "hiding" | "unknown" = isExpected
+ ? "hiding"
+ : "unknown";
+ for (let i = 0; i < trace.length; i++) {
+ const name = trace[i].getFunctionName();
+ if (name === START_HIDING) {
+ status = "hiding";
+ } else if (name === STOP_HIDING) {
+ if (status === "hiding") {
+ status = "showing";
+ if (virtualFrames.has(err)) {
+ newTrace.unshift(...virtualFrames.get(err));
+ }
+ } else if (status === "unknown") {
+ // Unexpected internal error, show the full stack trace
+ newTrace = trace;
+ break;
+ }
+ } else if (status !== "hiding") {
+ newTrace.push(trace[i]);
+ }
+ }
- const { prepareStackTrace = defaultPrepareStackTrace } = Error;
+ return (originalPrepareStackTrace || defaultPrepareStackTrace)(err, newTrace);
+}
+
+function setupPrepareStackTrace() {
+ if (Error.prepareStackTrace === stackTraceRewriter) return;
+ originalPrepareStackTrace = Error.prepareStackTrace;
+ originalMaxStackTraceLimit = Error.stackTraceLimit;
// We add some extra frames to Error.stackTraceLimit, so that we can
// always show some useful frames even after deleting ours.
@@ -137,35 +193,12 @@ function setupPrepareStackTrace() {
MIN_STACK_TRACE_LIMIT,
);
- Error.prepareStackTrace = function stackTraceRewriter(err, trace) {
- let newTrace = [];
-
- const isExpected = expectedErrors.has(err);
- let status: "showing" | "hiding" | "unknown" = isExpected
- ? "hiding"
- : "unknown";
- for (let i = 0; i < trace.length; i++) {
- const name = trace[i].getFunctionName();
- if (name === START_HIDING) {
- status = "hiding";
- } else if (name === STOP_HIDING) {
- if (status === "hiding") {
- status = "showing";
- if (virtualFrames.has(err)) {
- newTrace.unshift(...virtualFrames.get(err));
- }
- } else if (status === "unknown") {
- // Unexpected internal error, show the full stack trace
- newTrace = trace;
- break;
- }
- } else if (status !== "hiding") {
- newTrace.push(trace[i]);
- }
- }
+ Error.prepareStackTrace = stackTraceRewriter;
+}
- return prepareStackTrace(err, newTrace);
- };
+function resetPrepareStackTrace() {
+ Error.prepareStackTrace = originalPrepareStackTrace;
+ Error.stackTraceLimit = originalMaxStackTraceLimit;
}
function defaultPrepareStackTrace(err: Error, trace: CallSite[]) {
diff --git a/packages/babel-core/test/errors-stacks.js b/packages/babel-core/test/errors-stacks.js
index 6332b3cdf119..360d9ac229d1 100644
--- a/packages/babel-core/test/errors-stacks.js
+++ b/packages/babel-core/test/errors-stacks.js
@@ -253,6 +253,9 @@ describe("@babel/core errors", function () {
});
it("internal errors have the full stack trace", function () {
+ // Remove `Error.prepareStackTrace` because `source-map-support` used `Array.prototype.map`
+ const { prepareStackTrace } = Error;
+ Error.prepareStackTrace = null;
expectError(() => {
const { map } = Array.prototype;
try {
@@ -268,18 +271,18 @@ describe("@babel/core errors", function () {
}).toMatchTemplate`\
Error: Internal error! This is a fake bug :)
at Array.map (/packages/babel-core/test/errors-stacks.js:_:_)
- at ${/loadOneConfig|findRootConfig/} (/packages/babel-core/src/config/files/configuration.ts:_:_)
+ at ${/loadOneConfig|findRootConfig/} (/packages/babel-core/lib/config/files/configuration.js:_:_)
at loadOneConfig.next ()
- at buildRootChain (/packages/babel-core/src/config/config-chain.ts:_:_)
+ at buildRootChain (/packages/babel-core/lib/config/config-chain.js:_:_)
at buildRootChain.next ()
- at loadPrivatePartialConfig (/packages/babel-core/src/config/partial.ts:_:_)
+ at loadPrivatePartialConfig (/packages/babel-core/lib/config/partial.js:_:_)
at loadPrivatePartialConfig.next ()
- at ${/loadFullConfig|loadConfig/} (/packages/babel-core/src/config/full.ts:_:_)
+ at ${/loadFullConfig|loadConfig/} (/packages/babel-core/lib/config/full.js:_:_)
at loadFullConfig.next ()
- at parse (/packages/babel-core/src/parse.ts:_:_)
+ at parse (/packages/babel-core/lib/parse.js:_:_)
at parse.next ()
at evaluateSync (/node_modules/gensync/index.js:_:_)
- at fn (/node_modules/gensync/index.js:_:_)
+ at sync (/node_modules/gensync/index.js:_:_)
at stopHiding - secret - don't use this - v1 (/packages/babel-core/src/errors/rewrite-stack-trace.ts:_:_)
at Module.parseSync (/packages/babel-core/src/parse.ts:_:_)
at /packages/babel-core/test/errors-stacks.js:_:_
@@ -288,6 +291,45 @@ Error: Internal error! This is a fake bug :)
at ... internal jest frames ...\
`;
// TODO(Babel 8): We do not need regexps anymore in the matcher above
+ Error.prepareStackTrace = prepareStackTrace;
+ });
+
+ it("should reset `Error.prepareStackTrace`", async function () {
+ const { prepareStackTrace } = Error;
+ Error.prepareStackTrace = null;
+ babel.parseSync("foo;", {
+ root: fixture("valid"),
+ });
+ expect(Error.prepareStackTrace).toBeNull();
+
+ await babel.parseAsync("foo;", {
+ root: fixture("valid"),
+ });
+ expect(Error.prepareStackTrace).toBeNull();
+
+ const errors = [];
+
+ try {
+ babel.parseSync("foo;", {
+ root: fixture("invalid-json"),
+ });
+ } catch (e) {
+ errors.push(e);
+ }
+ expect(Error.prepareStackTrace).toBeNull();
+
+ try {
+ await babel.parseAsync("foo;", {
+ root: fixture("invalid-json"),
+ });
+ } catch (e) {
+ errors.push(e);
+ }
+ expect(Error.prepareStackTrace).toBeNull();
+
+ expect(errors).toHaveLength(2);
+
+ Error.prepareStackTrace = prepareStackTrace;
});
nodeGte12("should not throw in `node --frozen-intrinsics`", function () {
From 950fb085f5023fb33dfab2e6e7a528b0e5705f88 Mon Sep 17 00:00:00 2001
From: Babel Bot <30521560+liuxingbaoyu@users.noreply.github.com>
Date: Fri, 22 Dec 2023 12:22:16 +0800
Subject: [PATCH 2/2] types
---
.../src/errors/rewrite-stack-trace.ts | 28 ++++++++-----------
1 file changed, 12 insertions(+), 16 deletions(-)
diff --git a/packages/babel-core/src/errors/rewrite-stack-trace.ts b/packages/babel-core/src/errors/rewrite-stack-trace.ts
index 01b9a588a1dd..f839daee0f51 100644
--- a/packages/babel-core/src/errors/rewrite-stack-trace.ts
+++ b/packages/babel-core/src/errors/rewrite-stack-trace.ts
@@ -94,28 +94,24 @@ export function beginHiddenCallStack(
if (!SUPPORTED) return fn;
return Object.defineProperty(
- function (...args: A): R {
+ function (...args: A) {
setupPrepareStackTrace();
let isAsync = false;
try {
const ret = fn(...args);
- // @ts-expect-error check if it's a promise
- if (typeof ret?.then !== "function") return ret;
+ if (typeof (ret as any)?.then !== "function") return ret;
isAsync = true;
- return (
- ret
- // @ts-expect-error checked above
- .catch(function (err) {
- err.stack;
- resetPrepareStackTrace();
- throw err;
- })
- .then(function (val: unknown) {
- resetPrepareStackTrace();
- return val;
- })
- );
+ return (ret as Promise)
+ .catch(function (err) {
+ err.stack;
+ resetPrepareStackTrace();
+ throw err;
+ })
+ .then(function (val: unknown) {
+ resetPrepareStackTrace();
+ return val;
+ }) as R;
} catch (err) {
err.stack;
throw err;