错误边界不会从 apollo 客户端捕获错误
Posted
技术标签:
【中文标题】错误边界不会从 apollo 客户端捕获错误【英文标题】:Error boundary doesn't catch error from apollo client 【发布时间】:2020-06-03 12:45:13 【问题描述】:我试图在顶层捕获一些错误,以展示世界上最漂亮的错误页面。
由于某种原因,我看到我的节点断开连接,但错误边界从未触发。
import React, useState, useEffect from 'react';
import ReactDOM from 'react-dom';
import ApolloClient, gql from 'apollo-boost';
const client = new ApolloClient( uri: "/graphql" );
const query = gql` items id `;
class ErrorBoundary extends React.Component
state = hasError: false ;
static getDerivedStateFromError(error: any)
return hasError: true ;
render()
if (this.state.hasError)
return <h1>Had error</h1>
else
return this.props.children;
function App()
const [data, setData] = useState<any>(null);
useEffect(() =>
client.query( query )
.then(res => setData(res))
.catch(err => console.warn("Error:", err); throw err; );
, []);
return <pre>Data: data</pre>;
ReactDOM.render(
<ErrorBoundary>
<App />
</ErrorBoundary>,
document.getElementById('root')
);
我在一个空的 create-react-app 项目中运行它。
我希望看到<h1>Had error</h1>
;我收到 CRA 未处理的错误屏幕。
【问题讨论】:
错误边界只会在生产版本中显示。您如何通过测试看到自己的界限? 错误边界绝对适用于任何地方。只有调试错误覆盖没有在生产中显示。我通过使用yarn start
运行 cra 来测试它(然后我从反应中看到调试窗口),并在生产中使用 yarn build
&& npx serve build
(显示带有“数据:”字符串的窗口(所以 hasError
永远不会去真的)
【参考方案1】:
来自docs
错误边界不捕获以下错误:
事件处理程序(了解更多) 异步代码(例如 setTimeout 或 requestAnimationFrame 回调) 服务器端渲染 在错误边界本身(而不是其子项)中引发的错误
Promise 是异步的,因此被拒绝的 Promise 不会被错误边界捕获。目前,recommended but somewhat hackish approach 是在setState
中抛出错误。在功能组件中,可以使用useState
钩子返回的set函数代替setState
:
const [, setState] = useState()
useEffect(() =>
client.query( query )
.then(res => setData(res))
.catch(err =>
console.warn("Error:", err);
setState(() =>
throw err;
);
);
, []);
在useEffect
内部也可以使用,但在Promise 的then
或catch
回调中不行。您也不能将 useEffect
回调设为 async
函数,因为它不能返回 Promise。所以我们坚持使用setState
。
还请注意,实际上没有理由直接调用client.query
,尤其是因为如果缓存发生更改,此代码将不会重新呈现您的 UI。您应该使用 useQuery
和钩子已经为您公开的 data
状态。
【讨论】:
感谢您的回答!那行得通。关于useQuery,这个例子是一个最小的复制案例,在现实世界中它是一个加载事件数据的查询,所以很遗憾使用useQuery不起作用。 @yhaskell 明白了。您可能要考虑使用useLazyQuery
代替。此外,虽然我想通过相同的机制处理所有错误,但您可能会考虑添加一个 ErrorLink 来为 Apollo 客户端进行全局错误处理,并将错误边界用于其他所有内容。即使有一些重复,它仍然可能整体上更干净。只是一个建议。以上是关于错误边界不会从 apollo 客户端捕获错误的主要内容,如果未能解决你的问题,请参考以下文章
如何防止 Apollo 客户端 useQuery 中的错误传播?
React JS + Apollo 客户端查询错误:“网络错误:无法获取”。从手机打电话时