Debugging Apollo客户端:如何简单地调试400代码错误?

Debugging Apollo客户端:如何简单地调试400代码错误?,debugging,graphql,apollo,Debugging,Graphql,Apollo,我正在使用Apollo客户端,我不明白为什么调试我的错误如此困难: 我正在尝试对GraphQL的graphene python实现执行一个变种调用。它以400个错误代码结束,我没有办法检索信息 例如:当我在/graphQL接口上尝试graphene服务时,它会返回一些有用的错误,如错误的输入或错误的方法名。 这里,在apollo客户端上,它只给我抛出了一个400代码错误。那对我一点帮助都没有。那么,有没有可能从我的apolo客户端获得graphene的错误信息,而不是无用的400代码错误 下面是

我正在使用Apollo客户端,我不明白为什么调试我的错误如此困难: 我正在尝试对GraphQL的graphene python实现执行一个变种调用。它以400个错误代码结束,我没有办法检索信息

例如:当我在/graphQL接口上尝试graphene服务时,它会返回一些有用的错误,如错误的输入或错误的方法名。 这里,在apollo客户端上,它只给我抛出了一个400代码错误。那对我一点帮助都没有。那么,有没有可能从我的apolo客户端获得graphene的错误信息,而不是无用的400代码错误

下面是一个示例,来自我的graphene接口(/graphQL):

将输出:

{
  "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"
}