Skip to content

Commit 0df009d

Browse files
committed
Run onError, onShellError and onFatalError in the debugTask Context
1 parent dee1a71 commit 0df009d

File tree

1 file changed

+94
-32
lines changed

1 file changed

+94
-32
lines changed

packages/react-server/src/ReactFizzServer.js

Lines changed: 94 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,20 +1017,31 @@ function logPostpone(
10171017
request: Request,
10181018
reason: string,
10191019
postponeInfo: ThrownInfo,
1020+
debugTask: null | ConsoleTask,
10201021
): void {
10211022
// If this callback errors, we intentionally let that error bubble up to become a fatal error
10221023
// so that someone fixes the error reporting instead of hiding it.
1023-
request.onPostpone(reason, postponeInfo);
1024+
const onPostpone = request.onPostpone;
1025+
if (__DEV__ && enableOwnerStacks && debugTask) {
1026+
debugTask.run(onPostpone.bind(null, reason, postponeInfo));
1027+
} else {
1028+
onPostpone(reason, postponeInfo);
1029+
}
10241030
}
10251031

10261032
function logRecoverableError(
10271033
request: Request,
10281034
error: any,
10291035
errorInfo: ThrownInfo,
1036+
debugTask: null | ConsoleTask,
10301037
): ?string {
10311038
// If this callback errors, we intentionally let that error bubble up to become a fatal error
10321039
// so that someone fixes the error reporting instead of hiding it.
1033-
const errorDigest = request.onError(error, errorInfo);
1040+
const onError = request.onError;
1041+
const errorDigest =
1042+
__DEV__ && enableOwnerStacks && debugTask
1043+
? debugTask.run(onError.bind(null, error, errorInfo))
1044+
: onError(error, errorInfo);
10341045
if (errorDigest != null && typeof errorDigest !== 'string') {
10351046
// We used to throw here but since this gets called from a variety of unprotected places it
10361047
// seems better to just warn and discard the returned value.
@@ -1045,14 +1056,24 @@ function logRecoverableError(
10451056
return errorDigest;
10461057
}
10471058

1048-
function fatalError(request: Request, error: mixed): void {
1059+
function fatalError(
1060+
request: Request,
1061+
error: mixed,
1062+
errorInfo: ThrownInfo,
1063+
debugTask: null | ConsoleTask,
1064+
): void {
10491065
// This is called outside error handling code such as if the root errors outside
10501066
// a suspense boundary or if the root suspense boundary's fallback errors.
10511067
// It's also called if React itself or its host configs errors.
10521068
const onShellError = request.onShellError;
1053-
onShellError(error);
10541069
const onFatalError = request.onFatalError;
1055-
onFatalError(error);
1070+
if (__DEV__ && enableOwnerStacks && debugTask) {
1071+
debugTask.run(onShellError.bind(null, error));
1072+
debugTask.run(onFatalError.bind(null, error));
1073+
} else {
1074+
onShellError(error);
1075+
onFatalError(error);
1076+
}
10561077
if (request.destination !== null) {
10571078
request.status = CLOSED;
10581079
closeWithError(request.destination, error);
@@ -1185,11 +1206,21 @@ function renderSuspenseBoundary(
11851206
error.$$typeof === REACT_POSTPONE_TYPE
11861207
) {
11871208
const postponeInstance: Postpone = (error: any);
1188-
logPostpone(request, postponeInstance.message, thrownInfo);
1209+
logPostpone(
1210+
request,
1211+
postponeInstance.message,
1212+
thrownInfo,
1213+
__DEV__ && enableOwnerStacks ? task.debugTask : null,
1214+
);
11891215
// TODO: Figure out a better signal than a magic digest value.
11901216
errorDigest = 'POSTPONE';
11911217
} else {
1192-
errorDigest = logRecoverableError(request, error, thrownInfo);
1218+
errorDigest = logRecoverableError(
1219+
request,
1220+
error,
1221+
thrownInfo,
1222+
__DEV__ && enableOwnerStacks ? task.debugTask : null,
1223+
);
11931224
}
11941225
encodeErrorForBoundary(newBoundary, errorDigest, error, thrownInfo, false);
11951226

@@ -1332,11 +1363,21 @@ function replaySuspenseBoundary(
13321363
error.$$typeof === REACT_POSTPONE_TYPE
13331364
) {
13341365
const postponeInstance: Postpone = (error: any);
1335-
logPostpone(request, postponeInstance.message, thrownInfo);
1366+
logPostpone(
1367+
request,
1368+
postponeInstance.message,
1369+
thrownInfo,
1370+
__DEV__ && enableOwnerStacks ? task.debugTask : null,
1371+
);
13361372
// TODO: Figure out a better signal than a magic digest value.
13371373
errorDigest = 'POSTPONE';
13381374
} else {
1339-
errorDigest = logRecoverableError(request, error, thrownInfo);
1375+
errorDigest = logRecoverableError(
1376+
request,
1377+
error,
1378+
thrownInfo,
1379+
__DEV__ && enableOwnerStacks ? task.debugTask : null,
1380+
);
13401381
}
13411382
encodeErrorForBoundary(
13421383
resumedBoundary,
@@ -2397,6 +2438,7 @@ function replayElement(
23972438
thrownInfo,
23982439
childNodes,
23992440
childSlots,
2441+
__DEV__ && enableOwnerStacks ? task.debugTask : null,
24002442
);
24012443
}
24022444
task.replay = replay;
@@ -2971,6 +3013,7 @@ function replayFragment(
29713013
thrownInfo,
29723014
childNodes,
29733015
childSlots,
3016+
__DEV__ && enableOwnerStacks ? task.debugTask : null,
29743017
);
29753018
}
29763019
task.replay = replay;
@@ -3361,7 +3404,12 @@ function injectPostponedHole(
33613404
reason: string,
33623405
thrownInfo: ThrownInfo,
33633406
): Segment {
3364-
logPostpone(request, reason, thrownInfo);
3407+
logPostpone(
3408+
request,
3409+
reason,
3410+
thrownInfo,
3411+
__DEV__ && enableOwnerStacks ? task.debugTask : null,
3412+
);
33653413
// Something suspended, we'll need to create a new segment and resolve it later.
33663414
const segment = task.blockedSegment;
33673415
const insertionIndex = segment.chunks.length;
@@ -3645,6 +3693,7 @@ function erroredReplay(
36453693
errorInfo: ThrownInfo,
36463694
replayNodes: ReplayNode[],
36473695
resumeSlots: ResumeSlots,
3696+
debugTask: null | ConsoleTask,
36483697
): void {
36493698
// Erroring during a replay doesn't actually cause an error by itself because
36503699
// that component has already rendered. What causes the error is the resumable
@@ -3661,11 +3710,11 @@ function erroredReplay(
36613710
error.$$typeof === REACT_POSTPONE_TYPE
36623711
) {
36633712
const postponeInstance: Postpone = (error: any);
3664-
logPostpone(request, postponeInstance.message, errorInfo);
3713+
logPostpone(request, postponeInstance.message, errorInfo, debugTask);
36653714
// TODO: Figure out a better signal than a magic digest value.
36663715
errorDigest = 'POSTPONE';
36673716
} else {
3668-
errorDigest = logRecoverableError(request, error, errorInfo);
3717+
errorDigest = logRecoverableError(request, error, errorInfo, debugTask);
36693718
}
36703719
abortRemainingReplayNodes(
36713720
request,
@@ -3684,6 +3733,7 @@ function erroredTask(
36843733
boundary: Root | SuspenseBoundary,
36853734
error: mixed,
36863735
errorInfo: ThrownInfo,
3736+
debugTask: null | ConsoleTask,
36873737
) {
36883738
// Report the error to a global handler.
36893739
let errorDigest;
@@ -3694,14 +3744,14 @@ function erroredTask(
36943744
error.$$typeof === REACT_POSTPONE_TYPE
36953745
) {
36963746
const postponeInstance: Postpone = (error: any);
3697-
logPostpone(request, postponeInstance.message, errorInfo);
3747+
logPostpone(request, postponeInstance.message, errorInfo, debugTask);
36983748
// TODO: Figure out a better signal than a magic digest value.
36993749
errorDigest = 'POSTPONE';
37003750
} else {
3701-
errorDigest = logRecoverableError(request, error, errorInfo);
3751+
errorDigest = logRecoverableError(request, error, errorInfo, debugTask);
37023752
}
37033753
if (boundary === null) {
3704-
fatalError(request, error);
3754+
fatalError(request, error, errorInfo, debugTask);
37053755
} else {
37063756
boundary.pendingTasks--;
37073757
if (boundary.status !== CLIENT_RENDERED) {
@@ -3857,11 +3907,11 @@ function abortTask(task: Task, request: Request, error: mixed): void {
38573907
'The render was aborted with postpone when the shell is incomplete. Reason: ' +
38583908
postponeInstance.message,
38593909
);
3860-
logRecoverableError(request, fatal, errorInfo);
3861-
fatalError(request, fatal);
3910+
logRecoverableError(request, fatal, errorInfo, null);
3911+
fatalError(request, fatal, errorInfo, null);
38623912
} else {
3863-
logRecoverableError(request, error, errorInfo);
3864-
fatalError(request, error);
3913+
logRecoverableError(request, error, errorInfo, null);
3914+
fatalError(request, error, errorInfo, null);
38653915
}
38663916
return;
38673917
} else {
@@ -3878,11 +3928,11 @@ function abortTask(task: Task, request: Request, error: mixed): void {
38783928
error.$$typeof === REACT_POSTPONE_TYPE
38793929
) {
38803930
const postponeInstance: Postpone = (error: any);
3881-
logPostpone(request, postponeInstance.message, errorInfo);
3931+
logPostpone(request, postponeInstance.message, errorInfo, null);
38823932
// TODO: Figure out a better signal than a magic digest value.
38833933
errorDigest = 'POSTPONE';
38843934
} else {
3885-
errorDigest = logRecoverableError(request, error, errorInfo);
3935+
errorDigest = logRecoverableError(request, error, errorInfo, null);
38863936
}
38873937
abortRemainingReplayNodes(
38883938
request,
@@ -3916,11 +3966,11 @@ function abortTask(task: Task, request: Request, error: mixed): void {
39163966
error.$$typeof === REACT_POSTPONE_TYPE
39173967
) {
39183968
const postponeInstance: Postpone = (error: any);
3919-
logPostpone(request, postponeInstance.message, errorInfo);
3969+
logPostpone(request, postponeInstance.message, errorInfo, null);
39203970
// TODO: Figure out a better signal than a magic digest value.
39213971
errorDigest = 'POSTPONE';
39223972
} else {
3923-
errorDigest = logRecoverableError(request, error, errorInfo);
3973+
errorDigest = logRecoverableError(request, error, errorInfo, null);
39243974
}
39253975
encodeErrorForBoundary(boundary, errorDigest, error, errorInfo, true);
39263976

@@ -3958,7 +4008,7 @@ function safelyEmitEarlyPreloads(
39584008
} catch (error) {
39594009
// We assume preloads are optimistic and thus non-fatal if errored.
39604010
const errorInfo: ThrownInfo = {};
3961-
logRecoverableError(request, error, errorInfo);
4011+
logRecoverableError(request, error, errorInfo, null);
39624012
}
39634013
}
39644014

@@ -4200,7 +4250,12 @@ function retryRenderTask(
42004250
const postponeInstance: Postpone = (x: any);
42014251

42024252
const postponeInfo = getThrownInfo(task.componentStack);
4203-
logPostpone(request, postponeInstance.message, postponeInfo);
4253+
logPostpone(
4254+
request,
4255+
postponeInstance.message,
4256+
postponeInfo,
4257+
__DEV__ && enableOwnerStacks ? task.debugTask : null,
4258+
);
42044259
trackPostpone(request, trackedPostpones, task, segment);
42054260
finishedTask(request, task.blockedBoundary, segment);
42064261
return;
@@ -4210,7 +4265,13 @@ function retryRenderTask(
42104265
const errorInfo = getThrownInfo(task.componentStack);
42114266
task.abortSet.delete(task);
42124267
segment.status = ERRORED;
4213-
erroredTask(request, task.blockedBoundary, x, errorInfo);
4268+
erroredTask(
4269+
request,
4270+
task.blockedBoundary,
4271+
x,
4272+
errorInfo,
4273+
__DEV__ && enableOwnerStacks ? task.debugTask : null,
4274+
);
42144275
return;
42154276
} finally {
42164277
if (__DEV__) {
@@ -4289,6 +4350,7 @@ function retryReplayTask(request: Request, task: ReplayTask): void {
42894350
errorInfo,
42904351
task.replay.nodes,
42914352
task.replay.slots,
4353+
__DEV__ && enableOwnerStacks ? task.debugTask : null,
42924354
);
42934355
request.pendingRootTasks--;
42944356
if (request.pendingRootTasks === 0) {
@@ -4342,8 +4404,8 @@ export function performWork(request: Request): void {
43424404
}
43434405
} catch (error) {
43444406
const errorInfo: ThrownInfo = {};
4345-
logRecoverableError(request, error, errorInfo);
4346-
fatalError(request, error);
4407+
logRecoverableError(request, error, errorInfo, null);
4408+
fatalError(request, error, errorInfo, null);
43474409
} finally {
43484410
setCurrentResumableState(prevResumableState);
43494411
ReactSharedInternals.H = prevDispatcher;
@@ -4927,8 +4989,8 @@ export function startFlowing(request: Request, destination: Destination): void {
49274989
flushCompletedQueues(request, destination);
49284990
} catch (error) {
49294991
const errorInfo: ThrownInfo = {};
4930-
logRecoverableError(request, error, errorInfo);
4931-
fatalError(request, error);
4992+
logRecoverableError(request, error, errorInfo, null);
4993+
fatalError(request, error, errorInfo, null);
49324994
}
49334995
}
49344996

@@ -4953,8 +5015,8 @@ export function abort(request: Request, reason: mixed): void {
49535015
}
49545016
} catch (error) {
49555017
const errorInfo: ThrownInfo = {};
4956-
logRecoverableError(request, error, errorInfo);
4957-
fatalError(request, error);
5018+
logRecoverableError(request, error, errorInfo, null);
5019+
fatalError(request, error, errorInfo, null);
49585020
}
49595021
}
49605022

0 commit comments

Comments
 (0)