我一直在审查Apollo文档,但我没有看到如何在Apollo客户端中处理服务器错误的信息.
例如,假设服务器要么:
如何在客户端处理?Apollo目前失败,出现以下错误:
未处理(在react-apollo中)错误:GraphQL错误:不能......
我想避免这种情况发生并处理这些错误.我怎么能用React Apollo这样做?
以供参考:
我目前正在使用React-Apollo和Redux.
我们已经实现了模式拼接,其中GraphQL服务器从两个远程服务器获取模式并将它们拼接在一起.当我们只使用Query和Mutations时,一切都运行正常,但现在我们有一个用例,我们甚至需要缝合订阅,远程模式已经通过它实现了auth.
我们很难搞清楚如何通过网关将connectionParams中收到的授权令牌从客户端传递到远程服务器.
这就是我们如何反省架构:
API网关代码:
const getLink = async(): Promise<ApolloLink> => {
const http = new HttpLink({uri: process.env.GRAPHQL_ENDPOINT, fetch:fetch})
const link = setContext((request, previousContext) => {
if (previousContext
&& previousContext.graphqlContext
&& previousContext.graphqlContext.request
&& previousContext.graphqlContext.request.headers
&& previousContext.graphqlContext.request.headers.authorization) {
const authorization = previousContext.graphqlContext.request.headers.authorization;
return {
headers: {
authorization
}
}
}
else {
return {};
}
}).concat(http);
const wsLink: any = new WebSocketLink(new SubscriptionClient(process.env.REMOTE_GRAPHQL_WS_ENDPOINT, {
reconnect: true,
// There is no way to update connectionParams dynamically without resetting connection
// connectionParams: () => …
Run Code Online (Sandbox Code Playgroud) apollo graphql apollo-server graphql-subscriptions graphql-tools
我现在正在学习GraphQL,在学习教程的过程中,我遇到了一些我无法理解的行为.假设我们已经在模式中定义了类型:
type Link {
id: ID!
url: String!
description: String!
postedBy: User
votes: [Vote!]!
}
Run Code Online (Sandbox Code Playgroud)
由于docs votes: [Vote!]!
意味着该字段应该是不可为空的,并且数组本身也应该是不可为空的.但是,在教程的作者显示查询示例之后,对于某些链接,它返回votes
字段的空数组.像这样:
{
"url": "youtube.com",
"votes": []
},
{
"url": "agar.io",
"votes": []
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:不是"非可空"在graphQL模式中意味着"空",或者它只是graphQL服务器的某种错误行为(我的意思是它返回任何数组而没有警告应该有一些由于模式) .
谢谢!
我们目前正在从Relay转向React Apollo 2.1,而我正在做的事似乎很可疑.
上下文:只有在用户通过身份验证(通过API密钥)时才能呈现某些组件,因此有一个Authenticator
组件可以保护树的其余部分.
在App.js
,它被这样使用(显然下面的所有片段都是最小的例子):
import React from 'react';
import Authenticator from './Authenticator';
import MyComponent from './MyComponent';
export default function App({ apiKey }) {
return (
<Authenticator apiKey={apiKey}
render={({ error, token }) => {
if (error) return <div>{error.message}</div>;
if (token) return <MyComponent token={token} />;
return <div>Authenticating...</div>;
}}
/>
);
}
Run Code Online (Sandbox Code Playgroud)
如果身份验证成功,MyComponent
则会进行呈现.
Authentication
在第一次渲染/挂载时将身份验证突变发送到服务器,并相应地调用渲染道具.
Authentication.js
看起来像这样:
import gql from 'graphql-tag';
import React from 'react';
import { Mutation } …
Run Code Online (Sandbox Code Playgroud) 我尝试在 GraphQL 的 Apollo 客户端中更改 addTypeName: false
apollo.create({
link: httpLinkWithErrorHandling,
cache: new InMemoryCache({ addTypename: false }),
defaultOptions: {
watchQuery: {
fetchPolicy: 'network-only',
errorPolicy: 'all'
}
}
Run Code Online (Sandbox Code Playgroud)
但它可以工作,并且会在控制台中抛出以下消息
fragmentMatcher.js:26 You're using fragments in your queries, but either don't have the addTypename:true option set in Apollo Client, or you are trying to write a fragment to the store without the __typename.Please turn on the addTypename option and include __typename when writing fragments so that Apollo Clientcan accurately match fragments.
Run Code Online (Sandbox Code Playgroud)
,
Could not …
Run Code Online (Sandbox Code Playgroud) 目前我有一个useLazyQuery
钩子,它在按下按钮时被触发(搜索表单的一部分)。
钩子行为正常,只有在按下按钮时才会触发。但是,一旦我触发它一次,它就会在每次组件重新渲染时触发(通常是由于状态更改)。
因此,如果我搜索一次,然后编辑搜索字段,结果会立即出现,而且我不必再次单击搜索按钮。
不是我想要的用户界面,如果您完全删除搜索文本(因为它试图将搜索文本null
作为变量进行搜索),它会导致错误,有什么方法可以防止useLazyQuery
在重新渲染时重新获取?
这可以使用useQuery
依赖于“搜索”状态来解决,当我单击按钮时,该状态会被切换。但是,我宁愿看看是否可以避免增加组件的复杂性。
const AddCardSidebar = props => {
const [searching, toggleSearching] = useState(false);
const [searchParams, setSearchParams] = useState({
name: ''
});
const [searchResults, setSearchResults] = useState([]);
const [selectedCard, setSelectedCard] = useState();
const [searchCardsQuery, searchCardsQueryResponse] = useLazyQuery(SEARCH_CARDS, {
variables: { searchParams },
onCompleted() {
setSearchResults(searchCardsQueryResponse.data.searchCards.cards);
}
});
...
return (
<div>
<h1>AddCardSidebar</h1>
<div>
{searchResults.length !== 0 &&
searchResults.map(result => {
return (
<img
key={result.scryfall_id}
src={result.image_uris.small}
alt={result.name}
onClick={() => setSelectedCard(result.scryfall_id)}
/> …
Run Code Online (Sandbox Code Playgroud) listEvents
,但当我加载页面时,我发现该查询在我的活动查询中出现了两次。对于任何新查询来说似乎都是相同的。谢谢,
我正在使用Apollo-client而且我不明白为什么这么难调试我的错误:我正在尝试对我的石墨烯python实现GraphQL执行mutate调用.最终得到400错误代码,我无法检索信息.
例如:当我在/ graphQL接口上尝试我的石墨烯服务时,它会将有用的错误作为错误输入或错误的方法名称返回给我.在这里,在apollo客户端,它只给我一个400代码错误.这对我没有任何帮助.那么有可能从我的apolo客户端获取石墨烯的错误信息,而不是无用的400代码错误吗?
这是一个例子,来自我的石墨烯界面(/ graphQL):
mutation myMutation {
uploadFile(input:"") {
success
}
}
Run Code Online (Sandbox Code Playgroud)
将输出:
{
"errors": [
{
"message": "Argument \"input\" has invalid value \"\".\nExpected \"UploadFileMutationInput\", found not an object.",
"locations": [
{
"column": 20,
"line": 2
}
]
}
]
}
Run Code Online (Sandbox Code Playgroud)
当我在apollo客户端(js)上尝试相同时:
client.mutate({
mutation: gql`
mutation($file: Upload!) {
uploadFile(input: $file) {
success
}
}
`,
variables: { file } })
.then(console.log)
.catch((e) => { console.log("catch", e) })
Run Code Online (Sandbox Code Playgroud)
我明白了
Error: Network error: Response not successful: Received status code 400
我的捕获从未被调用过,文档根本没有帮助我. …
对于这个长问题,我深表歉意,但我非常感谢您对 Apollo Client 3 中缓存失效和重新获取查询的最佳策略的一些想法/帮助。
首先,关于我想象的场景的一些信息:
Account
组件(下面的示例)使用useQuery
react-apollo 中的钩子来获取和显示有关帐户的一些基本信息以及该帐户的交易列表CreateTransactionForm
组件使用突变来插入新事务。这是一个单独的组件,它位于组件树中的不同位置,不一定是AccountComponent
)我的Account
组件的简单版本可能如下所示:
import { gql, useQuery } from '@apollo/client';
import React from 'react';
import { useParams } from 'react-router-dom';
const GET_ACCOUNT_WITH_TRANSACTIONS = gql`
query getAccountWithTransactions($accountId: ID!) {
account(accountId: $accountId) {
_id
name
description
currentBalance
transactions {
_id
date
amount
runningBalance
}
}
}
`;
export const Account: React.FunctionComponent = () => {
const { accountId } …
Run Code Online (Sandbox Code Playgroud) 所以我们正在使用 Apollo 和 GraphQL 创建一个 React-Native 应用程序。我正在使用基于 JWT 的身份验证(当用户同时登录activeToken和refreshToken 时),并希望实现一个流程,当服务器注意到它已过期时,令牌会自动刷新。
Apollo-Link-Error 的 Apollo Docs 提供了一个很好的起点来捕获来自 ApolloClient 的错误:
onError(({ graphQLErrors, networkError, operation, forward }) => {
if (graphQLErrors) {
for (let err of graphQLErrors) {
switch (err.extensions.code) {
case 'UNAUTHENTICATED':
// error code is set to UNAUTHENTICATED
// when AuthenticationError thrown in resolver
// modify the operation context with a new token
const oldHeaders = operation.getContext().headers;
operation.setContext({
headers: {
...oldHeaders,
authorization: getNewToken(),
},
});
// …
Run Code Online (Sandbox Code Playgroud) apollo ×10
graphql ×7
reactjs ×4
javascript ×3
react-apollo ×3
caching ×1
debugging ×1
graphql-js ×1
node.js ×1
react-hooks ×1
react-native ×1