当响应源自微服务时,GraphQL如何处理错误消息

时间:2018-10-31 18:05:11

标签: node.js express error-handling graphql

我有一个API,当传入无效的授权令牌时,它会做出如下响应:

未经授权的回复:

{
   "status": "failure",
   "message": "Unauthorized" 
}

但是,当传入有效令牌时,它将以对象数组作为响应,每个对象都代表一个文档,如下所示:

授权回复:

[{
    "_id": "5bd8f520e68ba2003ec9f528",
    "user": "5bd8f50cced689002769d254",
    "title": "A title for a document",
    "content": "Some content for a document",
}, { 
    "_id": "5bd8f520e68ba2003ec9f528",
    "user": "5bd8f50cced689002769d254",
    ....
}]
  

当GraphQL中的错误响应出现时,我该如何优雅地处理它们   源自我运行的微服务快递?以及如何涵盖响应中数据结构的变化?

我的解析器:

const getDocuments = async context => {
  const config = {
    headers: {
      Authorization: context.token
    }
  };

  try {
    return await axios
      .get("http://document_service:4000/v1/documents", config)
      .then(response => {
        return response.data;
      })
      .catch(error => {
        return error.data;
      });
  } catch (err) {
    return err;
  }
};

const Query = {
  docServiceGetDocs: (obj, args, context) => getDocuments(context)
};

response.data 将返回文档数组或带有状态和消息的对象。

我的模式:

type getDocuments {
  _id: String
  user: String
  title: String
  content: String
}

type Query {
  docServiceGetDocs: [getDocuments]
}

[getDocuments] 我想这需要一个对象数组,但是不确定如果得到未经授权的响应作为对象,该如何处理。

我正在使用apollo服务器2

1 个答案:

答案 0 :(得分:2)

理想情况下,如果内容响应用于传达错误而不是状态代码,则无论状态如何,API的响应都将具有某种程度的一致性。

{
   "status": "failure",
   "message": "Unauthorized",
   "response": []
}

{
   "status": "success",
   "message": "",
   "response": [{ user: "Dan" }],
}

但是如果不容易解决,您可以检查解析器中响应的形状:

const getDocuments = async context => {
  const config = {
    headers: {
      Authorization: context.token
    }
  };

  try {
    const response = await axios.get("http://document_service:4000/v1/documents", config)
    const data = response.data
    if (data && data.status === 'failure') {
      throw new Error(data.message)
    }
    return data
  } catch (err) {
    // example of how to handle axios errors

    let message = ''
    if (err.response) {
      // Status code out of the range of 2xx, format error message according
    } else if (err.request) {
      // The request was made but no response was received, format message accordingly
    } else {
      message = err.message
    }
    // throw whatever error you have so it's included in your graphql response
    throw new Error(message) 
  }
};