Debugging Apollo客户端:如何简单地调试400代码错误?
我正在使用Apollo客户端,我不明白为什么调试我的错误如此困难: 我正在尝试对GraphQL的graphene python实现执行一个变种调用。它以400个错误代码结束,我没有办法检索信息 例如:当我在/graphQL接口上尝试graphene服务时,它会返回一些有用的错误,如错误的输入或错误的方法名。 这里,在apollo客户端上,它只给我抛出了一个400代码错误。那对我一点帮助都没有。那么,有没有可能从我的apolo客户端获得graphene的错误信息,而不是无用的400代码错误 下面是一个示例,来自我的graphene接口(/graphQL): 将输出:Debugging Apollo客户端:如何简单地调试400代码错误?,debugging,graphql,apollo,Debugging,Graphql,Apollo,我正在使用Apollo客户端,我不明白为什么调试我的错误如此困难: 我正在尝试对GraphQL的graphene python实现执行一个变种调用。它以400个错误代码结束,我没有办法检索信息 例如:当我在/graphQL接口上尝试graphene服务时,它会返回一些有用的错误,如错误的输入或错误的方法名。 这里,在apollo客户端上,它只给我抛出了一个400代码错误。那对我一点帮助都没有。那么,有没有可能从我的apolo客户端获得graphene的错误信息,而不是无用的400代码错误 下面是
{
"errors": [
{
"message": "Argument \"input\" has invalid value \"\".\nExpected \"UploadFileMutationInput\", found not an object.",
"locations": [
{
"column": 20,
"line": 2
}
]
}
]
}
当我在apollo客户端(js)上尝试同样的方法时:
我明白了
错误:网络错误:响应未成功:收到状态代码400
我的捕获从未被调用,文档对我毫无帮助
我想要的是得到我调用的变异细节错误:当我使用不正确的方法调用或错误的输入类型时,如果没有任何导致我的请求错误的信息,我不应该陷入400 我通过将
onError
函数直接放在客户机配置中实现了这一点(graphQLErrors
在数据库中执行时始终为空):
const客户端=新客户端({
uri:'http://localhost:3000/graphql',
onError:(e)=>{console.log(e)},
});
您应该使用此链接:在实例化ApolloClient
时。它应该先于其他链接,如:
从'apollo boost'导入{apollo客户端,apollo链接}
从“阿波罗链接错误”导入{onError}
const errorLink=onError({graphQLErrors})=>{
if(graphQLErrors)graphQLErrors.map(({message})=>console.log(message))
})
新阿波罗客户({
...
链接:ApolloLink.from([errorLink,authLink,restLink,httpLink]),
})
这个解决方案为我解决了这个问题:
const client = new ApolloClient({
uri: 'http://localhost:4444/graphql',
onError: ({ networkError, graphQLErrors }) => {
console.log('graphQLErrors', graphQLErrors)
console.log('networkError', networkError)
}
})
就我而言,查询中有一个输入错误。 然而,它最终以400错误而告终 要调试此类情况,只需使用以下代码:
function query() {
try {
/**
* DO QUERY
*/
} catch (e) {
// Here you can catch any errors from Apollo Error.
console.log(e.networkError.result.errors);
}
}
提示:GraphQL错误不会总是以graphQLErrors
结束,因此最好将网络错误与GraphQL错误一起检查。
要查看GraphQL错误:console.log(e.graphQLErrors)代码>请注意graphQLErrors
将是一个数组
以下是一个完整的示例:
async function userQueryInterface(userid = '1234', usermail = 'test@test.test') {
try {
let users = await client.query({
query: gql`
query GetUsers($userid: ID!, $usermail: String) {
getUsers(vlanid: $userid, usermail: $usermail) {
_id
mail
}
}
`,
variables: { userid, usermail }
});
return users.data.getUsers;
} catch (e) {
console.log(e.networkError.result.errors); // here you can see your network
}
}
错误
和控制台。日志
惊喜
尝试使用console.log
查看错误时,您可能会惊讶地发现没有看到所有可用的错误数据。这是因为console.log
以特殊方式处理作为内置Error
类实例的值,只打印消息、类型和堆栈
Apollo从内置的Error
类扩展了自己的错误。这可以通过以下方式轻松测试:
const error=apolloError//来自异步try/catch、onError方法或promise.catch
console.log(error instanceof error);
//是的
从Error
扩展时,Apollo将向对象添加自己的数据。但是错误仍然是错误的一个实例,因此console.log只显示有限的信息量
console.log(错误);
//输出:
//错误:网络错误:响应不成功:收到状态代码400
//在。。。
//在。。。
//在。。。
建议(解决方案?)
如果知道要查找的位置,只需在error对象上执行属性查找即可。例如,您可以记录error.networkError.result.errors
。这种方法可能过于外科手术,导致对所有出错情况的不完整描述
或者,我们可以在error对象上使用JSON.stringify
,将所有数据打印到控制台
//提示:使用stringify的格式选项以提高可读性
log(JSON.stringify(error,null,2));
你一眼就能看出哪里出了问题。这应该在你的变异选项中使用选项:()=>({errorPolicy:'all'}),
完成,但我仍然没有成功。。。我不明白为什么没有一个清晰的例子来记录它。它确实对我有用。也许你应该解释一下你的问题,而不是直接投反对票。实际上,Almaju
和陌生人的回答是相似的。在同伴
中,在传递给函数之前销毁错误对象@Almaju我更愿意记录整个错误对象console.log(e)
,bcz根据错误,一些子对象可能会发生,也可能不会发生。为什么它必须在其他链接之前发生?@VladyslavZavalykhatkoI认为这是阿波罗文档中的某个地方说的。很早以前,所以不确定。@YanTakushevich我没有errorLink之后的所有链接。当我没有包含链接时(我现在是如何拥有的),我的查询工作正常,但当我包含errorLink时,我就不能再查询数据库了。你有什么建议吗?@financial\u如果你使用的是“@apollo/client”,你应该改用它。有关更多信息,请参阅本节:感谢您的评论!我不知道去哪里找,而且error.networkError.result.errors
中有我需要的明确错误!此解决方案实际上与上面的@Yan Takushevich相同,但不需要任何额外的库。Apollo在这里提供了文档:这不再是正确的,现在这样说:newApollo客户端({link:new-HttpLink({onError:({networkError,graphqlerors})=>{console.log('graphqlerors',graphqlerors)console.log('networkError',networkError}),})代码>
function query() {
try {
/**
* DO QUERY
*/
} catch (e) {
// Here you can catch any errors from Apollo Error.
console.log(e.networkError.result.errors);
}
}
async function userQueryInterface(userid = '1234', usermail = 'test@test.test') {
try {
let users = await client.query({
query: gql`
query GetUsers($userid: ID!, $usermail: String) {
getUsers(vlanid: $userid, usermail: $usermail) {
_id
mail
}
}
`,
variables: { userid, usermail }
});
return users.data.getUsers;
} catch (e) {
console.log(e.networkError.result.errors); // here you can see your network
}
}
{
"graphQLErrors": [],
"networkError": {
"name": "ServerError",
"response": {},
"statusCode": 400,
"result": {
"errors": [...here you will find what you're looking for]
}
},
"message": "Network error: Response not successful: Received status code 400",
"name": "Error",
"stack": "...same as before"
}