From a1bec0709f1c4ef12feba2b060fef22384a24f43 Mon Sep 17 00:00:00 2001 From: Mengdi Chen Date: Fri, 25 Mar 2022 14:36:39 -0400 Subject: [PATCH] [ReactDebugTools] wrap uncaught error from rendering user's component --- .../react-debug-tools/src/ReactDebugHooks.js | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/packages/react-debug-tools/src/ReactDebugHooks.js b/packages/react-debug-tools/src/ReactDebugHooks.js index c013d3488d6a5..6603b36c871d9 100644 --- a/packages/react-debug-tools/src/ReactDebugHooks.js +++ b/packages/react-debug-tools/src/ReactDebugHooks.js @@ -667,6 +667,28 @@ function processDebugValues( } } +function handleRenderFunctionError(error: any): void { + // original error might be any type. + const isError = error instanceof Error; + if (isError && error.name === 'UnsupportedFeatureError') { + throw error; + } + // If the error is not caused by an unsupported feature, it means + // that the error is caused by user's code in renderFunction. + // In this case, we should wrap the original error inside a custom error + // so that devtools can show a clear message for it. + const messgae: string = + isError && error.message + ? error.message + : 'Error rendering inspected component' + // $FlowFixMe: Flow doesn't know about 2nd argument of Error constructor + const wrapperError = new Error(messgae, {cause: error}); + // Note: This error name needs to stay in sync with react-devtools-shared + // TODO: refactor this if we ever combine the devtools and debug tools packages + wrapperError.name = 'RenderFunctionError'; + throw wrapperError; +} + export function inspectHooks( renderFunction: Props => React$Node, props: Props, @@ -686,6 +708,8 @@ export function inspectHooks( try { ancestorStackError = new Error(); renderFunction(props); + } catch (error) { + handleRenderFunctionError(error); } finally { readHookLog = hookLog; hookLog = []; @@ -730,6 +754,8 @@ function inspectHooksOfForwardRef( try { ancestorStackError = new Error(); renderFunction(props, ref); + } catch (error) { + handleRenderFunctionError(error); } finally { readHookLog = hookLog; hookLog = [];