Skip to content

Commit 20e5bb6

Browse files
author
Brian Vaughn
committed
Added thrown error marks to Scheduling Profiler
1 parent 882c2e5 commit 20e5bb6

File tree

10 files changed

+350
-76
lines changed

10 files changed

+350
-76
lines changed

packages/react-devtools-scheduling-profiler/src/CanvasPage.js

Lines changed: 41 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import {
4949
SchedulingEventsView,
5050
SnapshotsView,
5151
SuspenseEventsView,
52+
ThrownErrorsView,
5253
TimeAxisMarkersView,
5354
UserTimingMarksView,
5455
} from './content-views';
@@ -138,6 +139,7 @@ const EMPTY_CONTEXT_INFO: ReactHoverContextInfo = {
138139
schedulingEvent: null,
139140
snapshot: null,
140141
suspenseEvent: null,
142+
thrownError: null,
141143
userTimingMark: null,
142144
};
143145

@@ -178,6 +180,7 @@ function AutoSizedCanvas({
178180
const flamechartViewRef = useRef(null);
179181
const networkMeasuresViewRef = useRef(null);
180182
const snapshotsViewRef = useRef(null);
183+
const thrownErrorsViewRef = useRef(null);
181184

182185
const {hideMenu: hideContextMenu} = useContext(RegistryContext);
183186

@@ -271,6 +274,20 @@ function AutoSizedCanvas({
271274
true,
272275
);
273276

277+
let thrownErrorsViewWrapper = null;
278+
if (data.thrownErrors.length > 0) {
279+
const thrownErrorsView = new ThrownErrorsView(
280+
surface,
281+
defaultFrame,
282+
data,
283+
);
284+
thrownErrorsViewRef.current = thrownErrorsView;
285+
thrownErrorsViewWrapper = createViewHelper(
286+
thrownErrorsView,
287+
'thrown errors',
288+
);
289+
}
290+
274291
const schedulingEventsView = new SchedulingEventsView(
275292
surface,
276293
defaultFrame,
@@ -382,6 +399,9 @@ function AutoSizedCanvas({
382399
}
383400
rootView.addSubview(nativeEventsViewWrapper);
384401
rootView.addSubview(schedulingEventsViewWrapper);
402+
if (thrownErrorsViewWrapper !== null) {
403+
rootView.addSubview(thrownErrorsViewWrapper);
404+
}
385405
if (suspenseEventsViewWrapper !== null) {
386406
rootView.addSubview(suspenseEventsViewWrapper);
387407
}
@@ -461,14 +481,7 @@ function AutoSizedCanvas({
461481
userTimingMarksView.onHover = userTimingMark => {
462482
if (!hoveredEvent || hoveredEvent.userTimingMark !== userTimingMark) {
463483
setHoveredEvent({
464-
componentMeasure: null,
465-
flamechartStackFrame: null,
466-
measure: null,
467-
nativeEvent: null,
468-
networkMeasure: null,
469-
schedulingEvent: null,
470-
snapshot: null,
471-
suspenseEvent: null,
484+
...EMPTY_CONTEXT_INFO,
472485
userTimingMark,
473486
});
474487
}
@@ -480,15 +493,8 @@ function AutoSizedCanvas({
480493
nativeEventsView.onHover = nativeEvent => {
481494
if (!hoveredEvent || hoveredEvent.nativeEvent !== nativeEvent) {
482495
setHoveredEvent({
483-
componentMeasure: null,
484-
flamechartStackFrame: null,
485-
measure: null,
496+
...EMPTY_CONTEXT_INFO,
486497
nativeEvent,
487-
networkMeasure: null,
488-
schedulingEvent: null,
489-
snapshot: null,
490-
suspenseEvent: null,
491-
userTimingMark: null,
492498
});
493499
}
494500
};
@@ -499,15 +505,8 @@ function AutoSizedCanvas({
499505
schedulingEventsView.onHover = schedulingEvent => {
500506
if (!hoveredEvent || hoveredEvent.schedulingEvent !== schedulingEvent) {
501507
setHoveredEvent({
502-
componentMeasure: null,
503-
flamechartStackFrame: null,
504-
measure: null,
505-
nativeEvent: null,
506-
networkMeasure: null,
508+
...EMPTY_CONTEXT_INFO,
507509
schedulingEvent,
508-
snapshot: null,
509-
suspenseEvent: null,
510-
userTimingMark: null,
511510
});
512511
}
513512
};
@@ -518,15 +517,8 @@ function AutoSizedCanvas({
518517
suspenseEventsView.onHover = suspenseEvent => {
519518
if (!hoveredEvent || hoveredEvent.suspenseEvent !== suspenseEvent) {
520519
setHoveredEvent({
521-
componentMeasure: null,
522-
flamechartStackFrame: null,
523-
measure: null,
524-
nativeEvent: null,
525-
networkMeasure: null,
526-
schedulingEvent: null,
527-
snapshot: null,
520+
...EMPTY_CONTEXT_INFO,
528521
suspenseEvent,
529-
userTimingMark: null,
530522
});
531523
}
532524
};
@@ -537,15 +529,8 @@ function AutoSizedCanvas({
537529
reactMeasuresView.onHover = measure => {
538530
if (!hoveredEvent || hoveredEvent.measure !== measure) {
539531
setHoveredEvent({
540-
componentMeasure: null,
541-
flamechartStackFrame: null,
532+
...EMPTY_CONTEXT_INFO,
542533
measure,
543-
nativeEvent: null,
544-
networkMeasure: null,
545-
schedulingEvent: null,
546-
snapshot: null,
547-
suspenseEvent: null,
548-
userTimingMark: null,
549534
});
550535
}
551536
};
@@ -559,15 +544,8 @@ function AutoSizedCanvas({
559544
hoveredEvent.componentMeasure !== componentMeasure
560545
) {
561546
setHoveredEvent({
547+
...EMPTY_CONTEXT_INFO,
562548
componentMeasure,
563-
flamechartStackFrame: null,
564-
measure: null,
565-
nativeEvent: null,
566-
networkMeasure: null,
567-
schedulingEvent: null,
568-
snapshot: null,
569-
suspenseEvent: null,
570-
userTimingMark: null,
571549
});
572550
}
573551
};
@@ -578,15 +556,8 @@ function AutoSizedCanvas({
578556
snapshotsView.onHover = snapshot => {
579557
if (!hoveredEvent || hoveredEvent.snapshot !== snapshot) {
580558
setHoveredEvent({
581-
componentMeasure: null,
582-
flamechartStackFrame: null,
583-
measure: null,
584-
nativeEvent: null,
585-
networkMeasure: null,
586-
schedulingEvent: null,
559+
...EMPTY_CONTEXT_INFO,
587560
snapshot,
588-
suspenseEvent: null,
589-
userTimingMark: null,
590561
});
591562
}
592563
};
@@ -600,15 +571,8 @@ function AutoSizedCanvas({
600571
hoveredEvent.flamechartStackFrame !== flamechartStackFrame
601572
) {
602573
setHoveredEvent({
603-
componentMeasure: null,
574+
...EMPTY_CONTEXT_INFO,
604575
flamechartStackFrame,
605-
measure: null,
606-
nativeEvent: null,
607-
networkMeasure: null,
608-
schedulingEvent: null,
609-
snapshot: null,
610-
suspenseEvent: null,
611-
userTimingMark: null,
612576
});
613577
}
614578
});
@@ -619,15 +583,20 @@ function AutoSizedCanvas({
619583
networkMeasuresView.onHover = networkMeasure => {
620584
if (!hoveredEvent || hoveredEvent.networkMeasure !== networkMeasure) {
621585
setHoveredEvent({
622-
componentMeasure: null,
623-
flamechartStackFrame: null,
624-
measure: null,
625-
nativeEvent: null,
586+
...EMPTY_CONTEXT_INFO,
626587
networkMeasure,
627-
schedulingEvent: null,
628-
snapshot: null,
629-
suspenseEvent: null,
630-
userTimingMark: null,
588+
});
589+
}
590+
};
591+
}
592+
593+
const {current: thrownErrorsView} = thrownErrorsViewRef;
594+
if (thrownErrorsView) {
595+
thrownErrorsView.onHover = thrownError => {
596+
if (!hoveredEvent || hoveredEvent.thrownError !== thrownError) {
597+
setHoveredEvent({
598+
...EMPTY_CONTEXT_INFO,
599+
thrownError,
631600
});
632601
}
633602
};

packages/react-devtools-scheduling-profiler/src/EventTooltip.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import type {
1919
SchedulingEvent,
2020
Snapshot,
2121
SuspenseEvent,
22+
ThrownError,
2223
UserTimingMark,
2324
} from './types';
2425

@@ -92,6 +93,7 @@ export default function EventTooltip({
9293
schedulingEvent,
9394
snapshot,
9495
suspenseEvent,
96+
thrownError,
9597
userTimingMark,
9698
} = hoveredEvent;
9799

@@ -118,6 +120,8 @@ export default function EventTooltip({
118120
content = <TooltipFlamechartNode stackFrame={flamechartStackFrame} />;
119121
} else if (userTimingMark !== null) {
120122
content = <TooltipUserTimingMark mark={userTimingMark} />;
123+
} else if (thrownError !== null) {
124+
content = <TooltipThrownError thrownError={thrownError} />;
121125
}
122126

123127
if (content !== null) {
@@ -436,3 +440,29 @@ const TooltipUserTimingMark = ({mark}: {|mark: UserTimingMark|}) => {
436440
</div>
437441
);
438442
};
443+
444+
const TooltipThrownError = ({thrownError}: {|thrownError: ThrownError|}) => {
445+
const {componentName, message, phase, timestamp} = thrownError;
446+
const label = `threw an error during ${phase}`;
447+
return (
448+
<div className={styles.TooltipSection}>
449+
{componentName && (
450+
<span className={styles.ComponentName}>
451+
{trimString(componentName, 100)}
452+
</span>
453+
)}
454+
<span className={styles.UserTimingLabel}>{label}</span>
455+
<div className={styles.Divider} />
456+
<div className={styles.DetailsGrid}>
457+
<div className={styles.DetailsGridLabel}>Timestamp:</div>
458+
<div>{formatTimestamp(timestamp)}</div>
459+
{message !== '' && (
460+
<>
461+
<div className={styles.DetailsGridLabel}>Error:</div>
462+
<div>{message}</div>
463+
</>
464+
)}
465+
</div>
466+
</div>
467+
);
468+
};

packages/react-devtools-scheduling-profiler/src/content-views/SchedulingEventsView.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ export class SchedulingEventsView extends View {
195195
};
196196
if (rectIntersectsRect(borderFrame, visibleArea)) {
197197
const borderDrawableRect = intersectionOfRects(borderFrame, visibleArea);
198-
context.fillStyle = COLORS.PRIORITY_BORDER;
198+
context.fillStyle = COLORS.REACT_WORK_BORDER;
199199
context.fillRect(
200200
borderDrawableRect.origin.x,
201201
borderDrawableRect.origin.y,

packages/react-devtools-scheduling-profiler/src/content-views/SuspenseEventsView.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ export class SuspenseEventsView extends View {
272272
borderFrame,
273273
visibleArea,
274274
);
275-
context.fillStyle = COLORS.PRIORITY_BORDER;
275+
context.fillStyle = COLORS.REACT_WORK_BORDER;
276276
context.fillRect(
277277
borderDrawableRect.origin.x,
278278
borderDrawableRect.origin.y,

0 commit comments

Comments
 (0)