Skip to content

Commit dd0eaba

Browse files
committed
Cache parsed stacks
Since we can only trigger prepareStackFrame once, it's important to cache this since the second time it gets accessed we won't be able to get to it.
1 parent 72bc9a6 commit dd0eaba

File tree

1 file changed

+17
-0
lines changed

1 file changed

+17
-0
lines changed

packages/react-server/src/ReactFlightServer.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,27 @@ function defaultFilterStackFrame(
152152
);
153153
}
154154

155+
// DEV-only cache of parsed and filtered stack frames.
156+
const stackTraceCache: WeakMap<Error, ReactStackTrace> = __DEV__
157+
? new WeakMap()
158+
: (null: any);
159+
155160
function filterStackTrace(
156161
request: Request,
157162
error: Error,
158163
skipFrames: number,
159164
): ReactStackTrace {
165+
const existing = stackTraceCache.get(error);
166+
if (existing !== undefined) {
167+
// Return a clone because the Flight protocol isn't yet resilient to deduping
168+
// objects in the debug info. TODO: Support deduping stacks.
169+
const clone = existing.slice(0);
170+
for (let i = 0; i < clone.length; i++) {
171+
// $FlowFixMe[invalid-tuple-arity]
172+
clone[i] = clone[i].slice(0);
173+
}
174+
return clone;
175+
}
160176
// Since stacks can be quite large and we pass a lot of them, we filter them out eagerly
161177
// to save bandwidth even in DEV. We'll also replay these stacks on the client so by
162178
// stripping them early we avoid that overhead. Otherwise we'd normally just rely on
@@ -183,6 +199,7 @@ function filterStackTrace(
183199
i--;
184200
}
185201
}
202+
stackTraceCache.set(error, stack);
186203
return stack;
187204
}
188205

0 commit comments

Comments
 (0)