Skip to content

Commit 5146d90

Browse files
committed
[ReactDebugTools] wrap uncaught error from rendering user's component
1 parent 60cb32b commit 5146d90

2 files changed

Lines changed: 29 additions & 1 deletion

File tree

packages/react-debug-tools/src/ReactDebugCustomErrors.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
export const ErrorsNames = {
1818
UNSUPPORTTED_FEATURE_ERROR: 'UnsupportedFeatureError',
19+
RENDER_FUNCTION_ERROR: "RenderFunctionError",
1920
};
2021

2122
// For now we just override the name. If we decide to move react-debug-tools to
@@ -25,3 +26,10 @@ export function createUnsupportedFeatureError(message: string = '') {
2526
error.name = ErrorsNames.UNSUPPORTTED_FEATURE_ERROR;
2627
return error;
2728
}
29+
30+
export function createRenderFunctionError(message: string = "", options: Object = {}) {
31+
// $FlowFixMe: Flow doesn't know about 2nd argument of Error constructor
32+
const error = new Error(message, options);
33+
error.name = ErrorsNames.RENDER_FUNCTION_ERROR;
34+
return error;
35+
}

packages/react-debug-tools/src/ReactDebugHooks.js

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ import {
2929
ContextProvider,
3030
ForwardRef,
3131
} from 'react-reconciler/src/ReactWorkTags';
32-
import {createUnsupportedFeatureError} from './ReactDebugCustomErrors';
32+
import {
33+
createUnsupportedFeatureError,
34+
createRenderFunctionError,
35+
ErrorsNames,
36+
} from './ReactDebugCustomErrors';
3337

3438
type CurrentDispatcherRef = typeof ReactSharedInternals.ReactCurrentDispatcher;
3539

@@ -666,6 +670,18 @@ function processDebugValues(
666670
}
667671
}
668672

673+
function handleRenderFunctionError(error: any): void {
674+
if (error instanceof Error && error.name === ErrorsNames.UNSUPPORTTED_FEATURE_ERROR) {
675+
throw error;
676+
}
677+
// If the error is not caused by an unsupported feature, it means
678+
// that the error is caused by user's code in renderFunction.
679+
// In this case, we should wrap the original error inside a custom error
680+
// so that devtools can show a clear message for it.
681+
// Note: original error might be any type.
682+
throw createRenderFunctionError('Error rendering inspected component', {cause: error});
683+
}
684+
669685
export function inspectHooks<Props>(
670686
renderFunction: Props => React$Node,
671687
props: Props,
@@ -685,6 +701,8 @@ export function inspectHooks<Props>(
685701
try {
686702
ancestorStackError = new Error();
687703
renderFunction(props);
704+
} catch (error) {
705+
handleRenderFunctionError(error);
688706
} finally {
689707
readHookLog = hookLog;
690708
hookLog = [];
@@ -729,6 +747,8 @@ function inspectHooksOfForwardRef<Props, Ref>(
729747
try {
730748
ancestorStackError = new Error();
731749
renderFunction(props, ref);
750+
} catch (error) {
751+
handleRenderFunctionError(error);
732752
} finally {
733753
readHookLog = hookLog;
734754
hookLog = [];

0 commit comments

Comments
 (0)