感谢您对此进行调查。所以我试图将我的 Apollo 服务器从 V3 迁移到 V4,我有一个解析器,它可以类型检查访问令牌并像这样返回它
export class LoginResolver {
@Mutation(() => AccessToken)
async login(
@Arg("email") email: string,
@Arg("password") password: string,
@Ctx() { prisma, res }: ProjectContext
): Promise<AccessToken> {
// check if user exists
const user = await prisma.user.findFirst({
where: {
email,
},
});
if (!user) {
throw new GraphQLError("No user found");
}
const valid = await verify(user.password, password);
if (!valid) {
throw new GraphQLError("Invalid Password");
}
// the user logged in successully
res.cookie("*****", createRefreshToken(user), { httpOnly: true });
const accessToken = createAccessToken(user);
return {
accessToken,
};
}
}
如果验证失败,它会返回以下错误。
{
"data": {},
"error": {
"message": "JSON.parse: unexpected character at line 1 column 1 of the JSON data"
}
}
但是,如果提供了正确的凭据,API 就可以正常工作并返回访问令牌
{
"data": {
"login": {
"accessToken": "..."
}
}
}
正确输入: 电子邮件:[电子邮件受保护] 密码: 密码
最初在 Apollo V3 中,我有标准的 throw 语句,效果很好
const user = await prisma.user.findFirst({
where: {
email,
},
});
if (!user) {
throw new Error("No user found");
}
const valid = await verify(user.password, password);
if (!valid) {
throw new Error("Invalid Password");
}
深入研究 Apollo 服务器的文档,我发现在 V4 Apollo 中错误已被删除,而 graphql 中的 GraphQLError 取代了它,我尝试了一下,但这似乎并没有解决它。
来自控制台的错误消息:
Unexpected error processing request: TypeError: graphqlError.toJSON is not a function
TypeError: graphqlError.toJSON is not a function
at enrichError (D:\Projects\PlacementHub\backend\node_modules\@apollo\server\src\errorNormalize.ts:84:30)
at D:\Projects\PlacementHub\backend\node_modules\@apollo\server\src\errorNormalize.ts:46:18
at Array.map (<anonymous>)
at normalizeAndFormatErrors (D:\Projects\PlacementHub\backend\node_modules\@apollo\server\src\errorNormalize.ts:39:29)
at ApolloServer.errorResponse (D:\Projects\PlacementHub\backend\node_modules\@apollo\server\src\ApolloServer.ts:1028:73)
at ApolloServer.executeHTTPGraphQLRequest (D:\Projects\PlacementHub\backend\node_modules\@apollo\server\src\ApolloServer.ts:1020:19)
我怀疑 GraphQLError 有一个强制性的第二个参数,如果省略它,Apollo 就不能很好地处理它。
尝试
throw new GraphQLError('"No user found', {
extensions: {
code: 'UNKNOWN_USER',
},
});
我从 v3 切换到 v4 时也遇到了类似的问题。如果您想在解析器中显示自定义错误,使用 GraphQLError 就足够了。
过去,它容忍
throw new Error
的使用。这种行为不再像以前那样有效。您必须使用 GraphQLError 来代替。如果你像过去一样抛出新的错误,你的服务器将停止工作。
我测试过且兼容的软件包版本:
"graphql": "16.8.1",
"@apollo/server": "4.9.4",
"express": "4.18.2",
GraphQL 具有三种不同的错误类型:
语法错误(例如,查询格式错误)
验证错误(例如,查询包含不存在的架构字段)
解析器错误(例如,尝试填充时发生错误 查询字段)
希望我对你有帮助。您可以查看文档以获取更多信息。顺便说一句,单独考虑 NodeJS 版本对你会有好处。
throw new GraphQLError('Invalid argument value', {
extensions: {
code: 'BAD_USER_INPUT',
},
});
https://www.apollographql.com/docs/react/data/error-handling
您应该为此使用 ApolloError。
import { ApolloError } from 'apollo-server-express';
throw new ApolloError("there is a big problem");
我在上面的代码行中为 Express 做了一个。您可以根据您的项目下载其他包。