如何在前端 apollo-client 上处理来自 Node/Koa 的后端错误

Posted

技术标签:

【中文标题】如何在前端 apollo-client 上处理来自 Node/Koa 的后端错误【英文标题】:How to handle backend errors from Node/Koa on frontend apollo-client 【发布时间】:2018-06-26 20:01:36 【问题描述】:

我的前端使用apollo-client,当后端在请求后返回错误时抛出异常。

当节点服务器收到请求时,我使用koa 中间件检查请求令牌的有效性。如果令牌有效,则将请求转发到下一个中​​间件。如果令牌无效,我想向客户端返回 401 拒绝访问错误。为此,我遵循了 Koa 的错误文档located here。

我写的错误处理中间件的代码:

function userIdentifier() 
  return async (ctx, next) => 
    const token = ctx.request.headers.authorization

    try 
      const payload = checkToken(token)
      ctx.user = 
        id: payload.userId,
        exp: payload.exp,
        iat: payload.iat,
      
     catch (error) 
      ctx.user = undefined
      ctx.throw(401, "access_denied")
      // throw new Error("access_denied")
    

    await next()
  

这似乎适用于后端,但不适用于前端。当前端收到此错误时,会发生 javascript 运行时错误。我不确定是什么原因造成的。

注意,意外的“a”与ctx.throw(401, "access_denied") 中的“a”相同。如果是 ctx.throw(401, "x"),则前端会显示“unexpected token x”。

发生错误的前端代码:

为了解决这个问题,我关注了Apollo's error handling documentation 并使用了apollo-link-error

const errorLink = onError(props => 
  const  graphQLErrors, networkError  = props
  console.log("ON ERROR", props)
  if (graphQLErrors)
    graphQLErrors.map(( message, locations, path ) =>
      console.log(
        `[GraphQL error]: Message: $message, Location: $locations, Path: $path`
      )
    )
  if (networkError) console.log(`[Network error]: $networkError`)
)

然后我将所有链接组合起来并像这样创建 Apollo 客户端:

const link = ApolloLink.from([errorLink, authLink, httpLink])

export const client = new ApolloClient(
  link,
  cache: new InMemoryCache(),
)

apollo-link-error中调试log的输出如下:

相关文件

似乎有人有identical error,但未列出解决方案。

【问题讨论】:

【参考方案1】:

当我开始在后端使用这个库时,我发现前端的错误得到了正确处理:https://github.com/jeffijoe/koa-respond

只使用ctx.unauthenticated()

但我仍然想了解更多关于如何在没有插件帮助的情况下使用 koa 返回基于 json/object 的错误

【讨论】:

以上是关于如何在前端 apollo-client 上处理来自 Node/Koa 的后端错误的主要内容,如果未能解决你的问题,请参考以下文章

使用 React 钩子处理 graphQL 突变错误(useMutation + Apollo-client)

无法理解 apollo-client 中解析器的使用

是否可以使用 apollo-client 跳过部分查询

apollo-client 没有响应的标头

如何将 localStorage 与 apollo-client 和 reactjs 一起使用?

如何在 apollo-client 中实现注销