Javascript GraphQL-如何使用不同的状态代码进行响应?
我的Graphql和Apollo客户端有问题 我总是在使用REST时创建不同的响应,比如401代码,但在这里我不知道如何做类似的行为 当我得到响应时,我希望它转到catch函数。 我的前端代码示例如下:Javascript GraphQL-如何使用不同的状态代码进行响应?,javascript,graphql,apollo,react-apollo,Javascript,Graphql,Apollo,React Apollo,我的Graphql和Apollo客户端有问题 我总是在使用REST时创建不同的响应,比如401代码,但在这里我不知道如何做类似的行为 当我得到响应时,我希望它转到catch函数。 我的前端代码示例如下: client.query({ query: gql` query TodoApp { todos { id text completed } } `, }) .then(data => co
client.query({
query: gql`
query TodoApp {
todos {
id
text
completed
}
}
`,
})
.then(data => console.log(data))
.catch(error => console.error(error));
有人能帮我吗?在GraphQL(至少在GraphQL js中)中返回错误的方法是在resolve函数中抛出错误。由于HTTP状态代码特定于HTTP传输,而GraphQL不关心传输,因此无法在那里设置状态代码。您可以改为在resolve函数中抛出特定错误:
age: (person, args) => {
try {
return fetchAge(person.id);
} catch (e) {
throw new Error("Could not connect to age service");
}
}
GraphQL错误会在响应中发送到客户端,如下所示:
{
"data": {
"name": "John",
"age": null
},
"errors": [
{ "message": "Could not connect to age service" }
]
}
如果消息没有足够的信息,您可以为GraphQL服务器创建一个特殊的错误类,其中包含一个状态代码。为了确保状态代码包含在响应中,您必须在创建中间件时指定formatError
函数:
app.use('/graphql', bodyParser.json(), graphqlExpress({
schema: myGraphQLSchema,
formatError: (err) => ({ message: err.message, status: err.status }),
}));
最近增加了一项有关错误的输出: GraphQL服务可能会使用键扩展提供额外的错误条目。如果设置了此条目,则其值必须为map。这个条目是为实现者保留的,他们可以在他们认为合适的情况下向错误添加额外的信息,并且对其内容没有额外的限制 现在,使用
extensions
字段,您可以为错误
条目自定义机器可读信息:
{
"errors": [
{
"message": "Name for character with ID 1002 could not be fetched.",
"locations": [ { "line": 6, "column": 7 } ],
"path": [ "hero", "heroFriends", 1, "name" ],
"extensions": {
"code": "CAN_NOT_FETCH_BY_ID",
"timestamp": "Fri Feb 9 14:33:09 UTC 2018"
}
}
]
}
最新版本的规范符合此功能。请查看。作为Glenn答案的补充,是Graphql规范的一部分,它定义了如何处理错误。因此,要知道请求是否失败(或部分失败),您可以检查响应根目录下的“errors”键。在尝试了一段时间后,我意识到缺少一些重要的细节。主要是,如果您有一个带有自定义字段的自定义错误对象,则上面的示例将允许您读取自定义属性,因为自定义错误似乎被强制转换到只有消息属性的标准
error
对象中
下面是我的formatError
函数的外观(请注意originalError
属性):
originalError
属性似乎总是设置好的,但作为一种保护措施,您可以使用lodashget
属性
我有一个定义的自定义错误类,名为apierro
class APIError extends Error {
constructor({ code, message }) {
const fullMsg = `${code}: ${message}`;
super(fullMsg);
this.code = code;
this.message = message;
}
}
export default APIError;
在我的解析器中,我抛出如下异常:
const e = new APIError({
code: 500,
message: 'Internal server error'
});
我认为关于graphql和错误的讨论中缺少的一个关注点是从http到gql的转换中的错误,而这正是401应该出现的地方 在转换请求时,您应该将授权头(或您正在使用的任何身份验证方法)转换为用户,如果无法对其进行身份验证,则应返回HTTP 401错误-这不是图形或api规范的一部分,只是用户是否可以验证的问题。您甚至不必检查查询 另一方面,403错误最有可能发生在gql层(并且可能不会使用http状态代码,但这是另一个讨论),因为它可能是非常特定于域的,您必须知道查询以决定它是否被禁止 HTTP403状态可以用来告诉用户他根本无法访问GQLAPI
在express/nestjs中,我们通过在到达graphql层之前使用一个中间件来解决这个问题,该层通过用户(可能未定义)来丰富请求,或者如果用户无法通过身份验证,则请求将失败。如果您不提供凭证(或类似的凭证),我认为401不应该被返回。谢谢helfer,它非常有用。
formatError`已被弃用,并被“customFormatErrorFn”取代。它将在1.0.0版中删除。
非常有用!
const e = new APIError({
code: 500,
message: 'Internal server error'
});