Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ export default function useInferredName(
const fetchFileWithCaching = useContext(FetchFileWithCachingContext);
const name = asyncInfo.awaited.name;
let inferNameFromStack = null;
if (!name || name === 'Promise') {
if (!name || name === 'Promise' || name === 'lazy') {
// If all we have is a generic name, we can try to infer a better name from
// the stack. We only do this if the stack has more than one frame since
// otherwise it's likely to just be the name of the component which isn't better.
Expand Down
31 changes: 27 additions & 4 deletions packages/react/src/ReactLazy.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {enableAsyncDebugInfo} from 'shared/ReactFeatureFlags';

import {REACT_LAZY_TYPE} from 'shared/ReactSymbols';

import noop from 'shared/noop';

const Uninitialized = -1;
const Pending = 0;
const Resolved = 1;
Expand Down Expand Up @@ -67,12 +69,20 @@ export type LazyComponent<T, P> = {

function lazyInitializer<T>(payload: Payload<T>): T {
if (payload._status === Uninitialized) {
let resolveDebugValue: (void | T) => void = (null: any);
let rejectDebugValue: mixed => void = (null: any);
if (__DEV__ && enableAsyncDebugInfo) {
const ioInfo = payload._ioInfo;
if (ioInfo != null) {
// Mark when we first kicked off the lazy request.
// $FlowFixMe[cannot-write]
ioInfo.start = ioInfo.end = performance.now();
// Stash a Promise for introspection of the value later.
// $FlowFixMe[cannot-write]
ioInfo.value = new Promise((resolve, reject) => {
resolveDebugValue = resolve;
rejectDebugValue = reject;
});
}
}
const ctor = payload._result;
Expand All @@ -92,12 +102,20 @@ function lazyInitializer<T>(payload: Payload<T>): T {
const resolved: ResolvedPayload<T> = (payload: any);
resolved._status = Resolved;
resolved._result = moduleObject;
if (__DEV__) {
if (__DEV__ && enableAsyncDebugInfo) {
const ioInfo = payload._ioInfo;
if (ioInfo != null) {
// Mark the end time of when we resolved.
// $FlowFixMe[cannot-write]
ioInfo.end = performance.now();
// Surface the default export as the resolved "value" for debug purposes.
const debugValue =
moduleObject == null ? undefined : moduleObject.default;
resolveDebugValue(debugValue);
// $FlowFixMe
ioInfo.value.status = 'fulfilled';
// $FlowFixMe
ioInfo.value.value = debugValue;
}
// Make the thenable introspectable
if (thenable.status === undefined) {
Expand All @@ -124,6 +142,14 @@ function lazyInitializer<T>(payload: Payload<T>): T {
// Mark the end time of when we rejected.
// $FlowFixMe[cannot-write]
ioInfo.end = performance.now();
// Hide unhandled rejections.
// $FlowFixMe
ioInfo.value.then(noop, noop);
rejectDebugValue(error);
// $FlowFixMe
ioInfo.value.status = 'rejected';
// $FlowFixMe
ioInfo.value.reason = error;
}
// Make the thenable introspectable
if (thenable.status === undefined) {
Expand All @@ -139,9 +165,6 @@ function lazyInitializer<T>(payload: Payload<T>): T {
if (__DEV__ && enableAsyncDebugInfo) {
const ioInfo = payload._ioInfo;
if (ioInfo != null) {
// Stash the thenable for introspection of the value later.
// $FlowFixMe[cannot-write]
ioInfo.value = thenable;
const displayName = thenable.displayName;
if (typeof displayName === 'string') {
// $FlowFixMe[cannot-write]
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/ReactIODescription.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ export function getIODescription(value: mixed): string {
}
try {
switch (typeof value) {
case 'function':
return value.name || '';
case 'object':
// Test the object for a bunch of common property names that are useful identifiers.
// While we only have the return value here, it should ideally be a name that
Expand Down
Loading