您好,我有这个登录API,它将请求正文如下:
{
"authentications": {
"emailAddress": "[email protected]",
"password": "11111111"
}
}
如果成功,服务器将返回令牌:
{
"authentications": {
"token": "eyJhbGoiU3RvcmUifV0sImNyZWF0ZWRBdCI6IjIwMTgtMDktMTZUMTg6NTA6NTYuNT"
}
}
如果电子邮件或密码输入不正确,它将返回:
{
"message": "Cannot find document for class 'User'. searched with parameters: '{\"emailAddress\":\"[email protected]\"}'",
"errorCode": 1103,
"status": 404
}
我可以使用GraphQL模式成功登录,如下所示:
gql`
fragment Authentications on any {
emailAddress: String
password: String
}
fragment AuthInput on REST {
authentications {
Authentications
}
}
mutation signIn($input: AuthInput!) {
authPayload(input: $input)
@rest(type: "AuthPayload", path: "/api/v1/authentications", endpoint:"UsersService", method:"POST") {
authentications @type(name:"Auth"){
token
}
}
}
`;
我的问题是在出现错误(错误的电子邮件/密码)的情况下如何获得响应? 因为现在如果服务器返回错误,则响应始终为null:
Object {
"data": Object {
"authPayload": null,
},
"errors": undefined,
}
如果您无法捕获400+错误,我认为此问题将非常有用。
https://github.com/apollographql/apollo-link-rest/issues/151
仅供参考:对于错误的凭据,您应该返回401。
https://stackoverflow.com/questions/1959947/whats-an-appropriate-http-status-code-to-return-by-a-rest-api-service-for-a-val
大家好,
我只是遇到这个问题,我也想知道处理404的推荐方法是什么。例如,它不会触发apollo-link-error
。
到目前为止,我正在考虑编写一个自定义错误处理程序链接,或者检查每个<Query />
组件的响应中的数据内容。
FWIW我也有相同的情况,例如服务器返回404而不是401,但是不幸的是,此时更改服务器不是一种选择。
我认为解决这个用例是值得的,因为REST的状态码与GraphQL的状态码是非常不同的-并且更加多样化和重要。
我也坚持这个问题。 是否有理由不返回完整的404响应,而不是返回null?
我还没有遇到过这样的情况:没有将404错误视为对我有帮助的错误,我一直在努力寻找解决该问题的好方法。
是否认为“ 404未找到”可以描述成功地正确产生空集的数据查询?
它还可能表明服务所有者进行了如此重大的更改,以至于先前可用的端点已消失。
我认为最好用200 OK以及空或空的应用程序实体来处理第一种情况。 至少,这两种情况似乎很容易被客户辨别,因为它们非常不同。
是的,有意为空的数据集比人们想象的普遍得多吗? (至少让我感到惊讶!)由于用户经常将多个网络和其他呼叫收集到单个meta呼叫中,因此默认情况下在404上引发错误会产生巨大的影响,因为404会终止并行发生的所有其他数据提取。 我同意,如果每个GraphQL查询只执行一个REST调用,在我看来,鉴于官方的REST语义,我们应该抛出一个错误。
实际上,默认情况下不抛出错误似乎更好! 由于您可以通过添加自定义抓取方法来解决此问题,因此感觉就像“在接受的内容上保持自由”; 这种选择似乎与Apollo-link-rest的主要目的之一相匹配:帮助不一定控制后端的用户,并且那里只有许多“主要是REST”服务器,因此语义冲突很常见。 。
@williamboman ,如果使用customFetch
参数,将Apollo-link-rest配置为抛出404相对简单,我不在电脑上,但是如果需要帮助,请告诉我!
嗨, @ fbartho,您能帮我编写customFetch处理404错误吗? 有一些例子吗?
@anasnain :
在javascript中,它看起来像这样:
export async function customFetch(requestInfo, init) {
const response = await fetch(requestInfo, init);
if (response.status === 404) {
throw new Error("404 File Not Found"); // Customize this however you like!
}
return response;
}
(在TypeScript中,它会更加冗长)
@fbartho感谢您的快速回复。 我现在可以抓到404。
但是,如何确定apollo-link-error的networkError捕获自定义提取中写入的错误(抛出新的Error(“ 404未找到文件”))?
啊,不幸的是,由于ApolloClient内部规则(关于链接的工作方式),我认为它会附加在graphQLErrors
数组上(不在networkError
属性上)。
这可能是可修复的,但我不知道如何。 -HTTPLink必须知道该怎么做,而我还没有机会进行调查。 我们的(工作)代码库中有一个辅助方法,可以解压缩嵌套的错误。 (这对于从apollo-link-state
给我们抛出的错误也是必要的,因此它并不是真正的优先事项)
@fbartho在这种情况下,我完全没有收到任何错误。 数据返回null。 如果我们抛出错误,那是在期待一个错误而不是数据。 不知道如何实现这一点。
@anasnain自设置以来已经很久了,我忘记了。
您还需要配置一个apollo-link-error实例,这是我的配置:
const attachGQLErrorsToNetworkError = (
graphQLErrors: readonly GraphQLError[],
networkError: Error,
): void => {
(networkError as any).tr_graphQLErrors = graphQLErrors;
return;
};
/** Set behavior when errors occur and handle our own TR errors */
export const apolloErrorLink = onError((errorResponse: ErrorResponse) => {
const {
graphQLErrors = [],
networkError,
}: {
graphQLErrors?: readonly GraphQLError[];
networkError?: Error;
} = errorResponse;
/**
* Our error parsing (function recursiveGQLErrorsFromNetworkError) rely
* on attaching the following graphql errors.
* Let's make sure to not attach anything `wrong` (ie: null, empty, ...)
*/
const hasGraphQLErrors: boolean =
graphQLErrors != null &&
Array.isArray(graphQLErrors) &&
graphQLErrors.length > 0;
if (networkError && hasGraphQLErrors) {
/*
* graphQLErrors are not being passed through the chain of links,
* but network errors are attaching the graphQLErrors to networkError
* to be able to access them in a component
*/
attachGQLErrorsToNetworkError(graphQLErrors, networkError);
}
});
经过进一步的思考:我不能完全确定我了解您所描述的情况。
是无法在组件/反应代码中读取“ 404错误”的问题吗?
@fbartho
场景:我在其余的APIquery下运行,期望是我应该得到一个错误对象,以防它返回404错误代码,就像其他4xx错误和5xx错误一样。 但是在这种情况下,错误是不确定的,并且数据为空。
const {loading,error,data} = useQuery(CLIENT_API_QUERY);
这是Apollo客户端实例:
async function customFetch(requestInfo, init) {
const response = await fetch(requestInfo, init);
if (response.status === 404) {
response.json().then((errorResponse) => {
throw new Error(errorResponse);
});
}
return response;
}
const errorLink = onError(({ operation, response, graphQLErrors, networkError }) => {
if (graphQLErrors) {
graphQLErrors.forEach(({ message, path }) =>
console.log(`[GraphQL error]: Message: ${message}, Path: ${path}`),
);
}
if (networkError) {
console.log(`[Network error ${operation.operationName}]: ${networkError.message}`);
}
});
const restLink = new RestLink({
uri: 'https://run.mocky.io/v3/df72bacd-39cb-476d-bfda-06d7f5e9d77d',
customFetch: (requestInfo, init) => customFetch(requestInfo, init)
});
const apolloClient = new ApolloClient({
link: ApolloLink.from([errorLink, restLink]),
new InMemoryCache(),
});
export default apolloClient;
@anasnain-我知道的一件事是,我认为您在执行new Error
时不能传递任意对象
另外,我认为您错过了一个等待,因此throw
语句发生在restLink customFetch调用之外!
const err = new Error("404 Error");
try {
err.responseJson = await response.json(); // This await crucial to get the error in the right spot!
} catch (parsingError) {
// figure out what you want to do with parsingError?
}
throw err;
最有用的评论
我也坚持这个问题。 是否有理由不返回完整的404响应,而不是返回null?