Skip to content

Commit 2340a3c

Browse files
authored
fix: preserve component stack on repeated element grabs (#2)
Fixed repeated grabs so the second and subsequent attempts keep the component stack instead of dropping it.
1 parent f10bca9 commit 2340a3c

1 file changed

Lines changed: 32 additions & 9 deletions

File tree

src/react-native/get-rendered-by.ts

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,34 @@ type V8CallSite = {
3232
getColumnNumber(): number | null;
3333
};
3434

35+
const restoreStackDescriptor = (error: Error, descriptor: PropertyDescriptor | undefined) => {
36+
try {
37+
if (descriptor) {
38+
Object.defineProperty(error, "stack", descriptor);
39+
} else {
40+
delete (error as Error & { stack?: unknown }).stack;
41+
}
42+
} catch {
43+
// Best effort only. Some runtimes may prevent restoring non-configurable properties.
44+
}
45+
};
46+
3547
const firstUserFrameFromError = (
3648
error: Error,
3749
): { file: string | null; line: number | null; column: number | null } | null => {
50+
const stackDescriptorBeforeCallSites = Object.getOwnPropertyDescriptor(error, "stack");
3851
let callSites: V8CallSite[] | null = null;
3952
const prev = (Error as any).prepareStackTrace;
40-
(Error as any).prepareStackTrace = (_: unknown, sites: V8CallSite[]) => {
41-
callSites = sites;
42-
return "";
43-
};
44-
void error.stack;
45-
(Error as any).prepareStackTrace = prev;
53+
try {
54+
(Error as any).prepareStackTrace = (_: unknown, sites: V8CallSite[]) => {
55+
callSites = sites;
56+
return "";
57+
};
58+
void error.stack;
59+
} finally {
60+
(Error as any).prepareStackTrace = prev;
61+
restoreStackDescriptor(error, stackDescriptorBeforeCallSites);
62+
}
4663

4764
if (callSites && (callSites as V8CallSite[]).length > 0) {
4865
const sites = callSites as V8CallSite[];
@@ -77,10 +94,16 @@ const firstUserFrameFromError = (
7794
return null;
7895
}
7996

97+
const stackDescriptorBeforeString = Object.getOwnPropertyDescriptor(error, "stack");
8098
const prevStr = (Error as any).prepareStackTrace;
81-
(Error as any).prepareStackTrace = undefined;
82-
let stack = error.stack ?? "";
83-
(Error as any).prepareStackTrace = prevStr;
99+
let stack = "";
100+
try {
101+
(Error as any).prepareStackTrace = undefined;
102+
stack = error.stack ?? "";
103+
} finally {
104+
(Error as any).prepareStackTrace = prevStr;
105+
restoreStackDescriptor(error, stackDescriptorBeforeString);
106+
}
84107

85108
if (stack.startsWith("Error: react-stack-top-frame\n")) {
86109
stack = stack.slice("Error: react-stack-top-frame\n".length);

0 commit comments

Comments
 (0)