【问题标题】:Apollo 客户端:如何简单调试 400 代码错误?
【发布时间】:2018-07-29 12:39:17
【问题描述】:

我正在使用 Apollo 客户端,但我不明白为什么调试我的错误如此困难: 我正在尝试对我的 GraphQL 的石墨烯 python 实现执行 mutate 调用。它以 400 错误代码结束,我无法检索信息。

例如:当我在 /graphQL 界面上尝试我的石墨烯服务时,它会向我返回有用的错误,例如错误的输入或错误的方法名称。 在这里,在阿波罗客户端上,它只会给我一个 400 代码错误。这对我一点帮助都没有。那么是否有可能从我的 apolo 客户端获得来自石墨烯的错误信息,而不是无用的 400 代码错误?

这是一个示例,来自我的石墨烯接口 (/graphQL):

mutation myMutation {
  uploadFile(input:"") {
    success
  }
}

将输出:

{
  "errors": [
    {
      "message": "Argument \"input\" has invalid value \"\".\nExpected \"UploadFileMutationInput\", found not an object.",
      "locations": [
        {
          "column": 20,
          "line": 2
        }
      ]
    }
  ]
}

当我在 apollo 客户端 (js) 上尝试相同的操作时:

client.mutate({
  mutation: gql`
    mutation($file: Upload!) {
      uploadFile(input: $file) {
        success
      }
    }
  `,
  variables: { file } })
  .then(console.log)
  .catch((e) => { console.log("catch", e) })

我明白了 Error: Network error: Response not successful: Received status code 400

我的 catch 从来没有被调用过,文档对我一点帮助也没有。

我想要的是获取我的调用的突变细节错误:当我使用不正确的方法调用或错误的输入类型时,我不应该在没有任何关于是什么导致我的请求错误的信息的情况下陷入 400。

【问题讨论】:

  • 这应该在您的突变选项中使用options: () => ({ errorPolicy: 'all' }), 完成,但我仍然不成功......我不明白为什么没有用一个明确的例子记录它。

标签: debugging graphql apollo


【解决方案1】:

我设法通过将onError 函数直接放在客户端配置中来做到这一点(在突变中执行此操作时graphQLErrors 始终为空):

const client = new ApolloClient({
  uri: 'http://localhost:3000/graphql',
  onError: (e) => { console.log(e) },
});

【讨论】:

  • 它确实对我有用。也许您应该解释您的问题,而不仅仅是投反对票。
  • 其实AlmajuFellow Stranger 的答案是相似的。在Fellow Stranger 中,错误对象的销毁在传递给函数之前完成。 @Almaju 我更愿意记录整个错误对象console.log(e), bcz 取决于错误,一些孩子可能会或可能不会发生
【解决方案2】:

您应该在实例化ApolloClient 时使用此链接:https://www.npmjs.com/package/apollo-link-error。它应该在其他链接之前,如下所示:

import { ApolloClient, ApolloLink } from 'apollo-boost'
import { onError } from 'apollo-link-error'

const errorLink = onError(({ graphQLErrors }) => {
  if (graphQLErrors) graphQLErrors.map(({ message }) => console.log(message))
})

new ApolloClient({
  ...
  link: ApolloLink.from([errorLink, authLink, restLink, httpLink]),
})

【讨论】:

  • 为什么要排在其他链接之前?
  • @VladyslavZavalykhatko我认为它在阿波罗文档中的某处有所说明。很久以前,所以不确定。
  • @YanTakushevich 我没有 errorLink 之后的所有链接。当我不包含链接(我现在如何拥有它)时,我的查询可以工作,但是当我包含 errorLink 时,我就不能再查询数据库了。你有什么建议吗?
  • @financial_physician 如果你使用'@apollo/client',你应该使用apollographql.com/docs/react/api/link/apollo-link-error。有关更多信息,请参阅此部分:apollographql.com/docs/react/api/link/apollo-link-error
【解决方案3】:

这个解决方案为我解决了这个问题:

const client = new ApolloClient({
  uri: 'http://localhost:4444/graphql',
  onError: ({ networkError, graphQLErrors }) => {
    console.log('graphQLErrors', graphQLErrors)
    console.log('networkError', networkError)
  }
})

【讨论】:

  • 这个解决方案实际上与上面的@Yan Takushevich 相同,但不需要任何额外的库。 Apollo 在此处提供文档:apollographql.com/docs/react/data/error-handling
  • 这不正确了,现在这样写:new ApolloClient({ link: new HttpLink({ onError: ({ networkError, graphQLErrors }) => { console.log('graphQLErrors', graphQLErrors) console.log('networkError', networkError) } }), });
【解决方案4】:

就我而言,查询中有错字。 但是最终出现 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
  }
}

【讨论】:

    【解决方案5】:

    Errorconsole.log 惊喜

    尝试使用console.log 查看错误时,您可能会惊讶地发现没有看到所有可用的错误数据。这是因为console.log 以特殊方式处理作为内置Error 类实例的值,仅打印消息、类型和堆栈。

    Apollo 从内置的 Error 类扩展了它自己的错误。这可以通过以下方式轻松测试:

    const error = apolloError // from async try/catch, onError method, or a promise .catch
    
    console.log(error instanceof Error);
    // --> true
    

    当从Error 扩展时,Apollo 会将它自己的数据添加到对象中。然而错误仍然是Error 的一个实例,因此console.log 只会显示有限的信息,

    console.log(error);
    
    // output:
    // Error: Network error: Response not successful: Received status code 400
    //     at ...
    //     at ...
    //     at ...
    

    建议(解决方案?)

    如果您知道在哪里查找,您可以对错误对象进行属性查找。例如,您可以记录error.networkError.result.errors。这种方法可能过于外科手术,并导致对所有错误的了解不完整。

    或者,我们可以在错误对象上使用JSON.stringify,整个数据将打印到控制台,

    // tip: use stringify's formatting options for better readability
    console.log(JSON.stringify(error, null, 2));
    
    {
      "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"
    }
    

    您一眼就能看出哪里出了问题。

    【讨论】:

    • 感谢您的评论!我不知道去哪里找,error.networkError.result.errors 有我需要的明显错误!
    猜你喜欢
    • 2019-04-16
    • 2018-08-26
    • 2017-12-01
    • 1970-01-01
    • 2012-07-04
    • 1970-01-01
    • 2013-08-26
    • 2022-08-02
    • 2022-10-17
    相关资源
    最近更新 更多