如何在 Relay 中捕获 GraphQL 错误消息?

Posted

技术标签:

【中文标题】如何在 Relay 中捕获 GraphQL 错误消息?【英文标题】:How to capture the GraphQL error message in Relay? 【发布时间】:2018-01-16 08:10:42 【问题描述】:

在我的服务器上,我使用 Flask、Graphene 和 SQLAlchemy 实现 GraphQL。理想情况下,我希望能够简单地操作标头并返回 401 错误响应,但 GraphQL 将所有内容都返回为 200。

使用 flask.abort(401) 但是我至少能够得到这个响应:

...
"errors": [
  
    "message": "401 Unauthorized: The server could not verify that you are authorized to access the URL requested.  You either supplied the wrong credentials (e.g. a bad password), or your browser doesn't understand how to supply the credentials required.",
    "locations": [
      
      "line": 11,
      "column": 3
      
    ]
  
]
...

我认为这是我目前可以使用的一种妥协。然而;因为没有什么可以这么简单...我不确定如何获取此错误消息。我已经读到 QueryRenderer 本身可能存在一个问题,它会吞下这些 GraphQL 错误,但我可以设法在 EnvironmentNetwork 对象中拦截它们......基本上看起来像这样。

Promise [[PromiseStatus]]: "resolved", [[PromiseValue]]: …
  __proto__: Promise[
    [PromiseStatus]]: "resolved"
    [[PromiseValue]]: Object
      data: viewer: …
      errors: Array(4)
        0: locations: Array(1), message: "401 Unauthorized: The server could not verify that…nderstand how to supply the credentials required."
        1: locations: Array(1), message: "401 Unauthorized: The server could not verify that…nderstand how to supply the credentials required."
        2: locations: Array(1), message: "401 Unauthorized: The server could not verify that…nderstand how to supply the credentials required."
        3: locations: Array(1), message: "401 Unauthorized: The server could not verify that…nderstand how to supply the credentials required."
      length: 4
      __proto__: Array(0)
    __proto__:Object

我真的不觉得在我的环境的网络层处理这个错误是管理这个错误的正确方法。 QueryRenderer 似乎是最有意义的......我基本上将它设置为单一的事实来源。

顺便说一句,如果这不是很明显,我正在使用 Relay Modern。因此,任何基于 Relay Classic 的解决方案都可能不适用。

编辑:除了错误消息,我这样做的动机是正确处理 JWT 令牌。我认为我正在寻找的解决方案与处理这些错误响应无关,而是扩展了我对 JWT 的理解。

我没有意识到我的客户可以使用 jwt-decode 之类的包轻松解码 JWT评估 JWT 上剩余的时间量以及是否需要刷新的实现。

【问题讨论】:

【参考方案1】:

您可以在onCompleted 回调中处理服务器错误:https://github.com/facebook/relay/pull/1938/files

【讨论】:

如何使用这个onCompletedcallback ?它在 Relay Modern 上可用吗?它也可用于查询吗? 它在 Relay Modern 上可用。我无法描述比文档更多的用法。是为了变种。这就是我在回答问题时遗漏的一点。【参考方案2】:

我希望我能正确理解您的问题,您的 QueryRenderer 应该有一个包含错误的错误对象 https://facebook.github.io/relay/docs/query-renderer.html

render=(error, props) => 
if (error) 
  return <div>error.message</div>;
 else if (props) 
  return <div>props.page.name is great!</div>;

return <div>Loading</div>;

【讨论】:

这些错误假定应用程序没有失败。事实证明,我毕竟不需要处理错误消息,但仅供参考,它指的是网络级别的环境错误,通常会导致应用程序出现严重故障。不幸的是,我不再有 sn-p 来演示。 好吧,这很有趣,所以 QueryRender 错误只在某些情况下触发,并且来自网络层的一些错误不会传播到 QueryRenderer?那很有意思。感谢您的信息。 QueryRenderer 错误仅在 GraphQL 有效负载数据为空时才会呈现,否则它会吞下它....【参考方案3】:

environment.js中,修改fetch函数,如果JSON响应中存在errors数组,你将把它作为一个新的自定义错误抛出。这个抛出的错误将被传输到QueryRenderer,在那里它将作为error 属性提供。如果存在错误,则通过显示与错误相关的 UI 来处理它。

详细解释见 GitHub 上的这条评论: https://github.com/facebook/relay/issues/1913#issuecomment-470541691

【讨论】:

以上是关于如何在 Relay 中捕获 GraphQL 错误消息?的主要内容,如果未能解决你的问题,请参考以下文章

中继/ graphql:可为空的响应或捕获查询错误的方法

如何进行示例 GraphQL Relay 突变

中继框架未捕获类型错误:this.props.relay.commitUpdate 不是函数

如何在 Relay 中捕获和处理失败的突变?

如何在 GraphQL (Relay) 中查询和改变数组类型?

React GraphQL Relay - 如何进行简单查询?