在组件端处理 Apollo 错误
Handling Apollo errors on the component side
问题
我如何对组件中的 Apollo 错误做出反应?
例如,如果抛出“网络离线”错误,我想显示一个红色横幅;如果显示某种类型的错误,则显示模式;如果抛出另一种错误,则渲染 <Redirect>
(来自 react-routed-dom
)。
我试过的
我阅读了文档 chapter about error handling,但它只解释了如何设置一个 Apollo link 作为请求的中间件,以便在那里捕获错误。据我所知,不可能将数据从 link 传递到组件,因为它是 终止 link.
我尝试使用 error boundary components,但似乎并没有真正抛出 Apollo 错误。即使使用 await
语法也不行。
正如您已经指出的,您可以使用 apollo-link-error
包
Link.
如果您还使用 react-router-dom
在页面之间进行路由,则可以使用浏览器历史记录或重定向组件重定向到带有状态对象 (routing history) 的错误页面。状态对象包含您要显示的错误。
设置可能如下所示:
- 创建浏览器历史记录
import { History, createBrowserHistory } from 'history';
/* If using Typescript, you can make this object Readonly as follows */
export type ReadonlyBrowserHistory = Readonly<History>
const browserHistory: ReadonlyBrowserHistory = createBrowserHistory();
export default browserHistory;
- 添加具有浏览器历史记录的路由器(w/ 使历史属性只读的选项)
import browserHistory from './browserHistory'
import apolloClient from './apolloClient'
...
ReactDOM.render((
<ApolloProvider client={apolloClient}>
<Router history={browserHistory}>
<App />
</Router>
</ApolloProvider>
), document.getElementById("root"));
- 添加 link 路由到 apollo 客户端
import browserHistory from './browserHistory'
const errorLink = onError(({ networkError, graphQLErrors }) => {
if (graphQLErrors) {
browserHistory.push("/error", { errors: graphQLErrors });
}
else if (networkError) {
browserHistory.push("/error", { errors: networkError });
};
});
const httpLink = new HttpLink({
uri: httpUri
});
const httpLinkWithErrorHandling = ApolloLink.from([
errorLink,
httpLink,
]);
const apolloClient = new ApolloClient({
link,
...
});
export default apolloClient;
- 错误页面可以从路由位置属性中检索错误
const ErrorPage = ({ location: { state } }) => {
console.log(state);
return (<div>error page</div>)
};
我通过将查询的 errorPolicy 设置为 none
解决了我的问题,然后您可以捕获从查询中抛出的 graphQLErrors
对象。
示例:
yourQuery()
.then()
.catch((error) => { error.graphQLErrors });
问题
我如何对组件中的 Apollo 错误做出反应?
例如,如果抛出“网络离线”错误,我想显示一个红色横幅;如果显示某种类型的错误,则显示模式;如果抛出另一种错误,则渲染 <Redirect>
(来自 react-routed-dom
)。
我试过的
我阅读了文档 chapter about error handling,但它只解释了如何设置一个 Apollo link 作为请求的中间件,以便在那里捕获错误。据我所知,不可能将数据从 link 传递到组件,因为它是 终止 link.
我尝试使用 error boundary components,但似乎并没有真正抛出 Apollo 错误。即使使用 await
语法也不行。
正如您已经指出的,您可以使用 apollo-link-error
包
Link.
如果您还使用 react-router-dom
在页面之间进行路由,则可以使用浏览器历史记录或重定向组件重定向到带有状态对象 (routing history) 的错误页面。状态对象包含您要显示的错误。
设置可能如下所示:
- 创建浏览器历史记录
import { History, createBrowserHistory } from 'history';
/* If using Typescript, you can make this object Readonly as follows */
export type ReadonlyBrowserHistory = Readonly<History>
const browserHistory: ReadonlyBrowserHistory = createBrowserHistory();
export default browserHistory;
- 添加具有浏览器历史记录的路由器(w/ 使历史属性只读的选项)
import browserHistory from './browserHistory'
import apolloClient from './apolloClient'
...
ReactDOM.render((
<ApolloProvider client={apolloClient}>
<Router history={browserHistory}>
<App />
</Router>
</ApolloProvider>
), document.getElementById("root"));
- 添加 link 路由到 apollo 客户端
import browserHistory from './browserHistory'
const errorLink = onError(({ networkError, graphQLErrors }) => {
if (graphQLErrors) {
browserHistory.push("/error", { errors: graphQLErrors });
}
else if (networkError) {
browserHistory.push("/error", { errors: networkError });
};
});
const httpLink = new HttpLink({
uri: httpUri
});
const httpLinkWithErrorHandling = ApolloLink.from([
errorLink,
httpLink,
]);
const apolloClient = new ApolloClient({
link,
...
});
export default apolloClient;
- 错误页面可以从路由位置属性中检索错误
const ErrorPage = ({ location: { state } }) => {
console.log(state);
return (<div>error page</div>)
};
我通过将查询的 errorPolicy 设置为 none
解决了我的问题,然后您可以捕获从查询中抛出的 graphQLErrors
对象。
示例:
yourQuery()
.then()
.catch((error) => { error.graphQLErrors });