gpt4 book ai didi

javascript - 将 catch block 添加到 Promise 会返回待处理而不是被拒绝

转载 作者:行者123 更新时间:2023-12-03 08:17:43 25 4
gpt4 key购买 nike

我有一个工作的 apollo graphql express 服务器。唯一的问题是 express 提示我在用来验证 jwt token 的 promise 上没有 catch block :

(node:96074) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch()


我可以在 promise 中添加一个 catch block ,但它会返回 pending而不是 rejected当 token 失效时。这会导致身份验证流程中断,因为我的 graphql 解析器依赖该拒绝来阻止对数据库的访问。
Fwiw 这就是我用于身份验证的 auth0 建议设置它的方式。他们只是没有提到 UnhandledPromiseRejectionWarning。
代码如下所示:
//server def
const server = new ApolloServer({
typeDefs,
resolvers,
context: ({ req }) => {
if (req.headers.authorization) {
const token = req.headers.authorization.split(' ')[1];

//THE PROMISE IN QUESTION
const authUserObj = new Promise((resolve, reject) => {
jwt.verify(token, getKey, options, (err, decoded) => {
if (err) {
reject(err);
}
if (decoded) {
resolve(decoded);
}
});
});

return {
authUserObj
};
}
},
introspection: true,
playground: true
});

//a graphql resolver that gets the rejection via authUserObj and catches the error
addUser: async (parent, args, {authUserObj}) => {
try {
const AuthUser = await authUserObj;
const response = await User.create(args);
return response;
} catch(err) {
throw new AuthenticationError('You must be logged in to do this');
}
}
一切正常……除了我希望克服的那个烦人的 Node 错误!所以我在 promise 中添加了一个 catch block :
 const authUserObj = new Promise((resolve, reject) => {
jwt.verify(token, getKey, options, (err, decoded) => {
if (err) {
console.log("-------rejected-------", err.message)
reject(err);
}
if (decoded) {
console.log("-------decoded-------")
resolve(decoded);
}
});
}).catch( err => { return err.message});
而现在 authUserObj 不是返回被拒绝,而是挂起,任何人都可以添加用户,这违背了 auth 的目的。
如果有人知道如何在仍然拒绝它的同时捕获该错误,我会全神贯注。谢谢。

最佳答案

问题不在于未处理的 promise 拒绝,而更多的是关于未处理的 promise 。您尝试在 context 中添加 promise 对象,然后 await addUser 中的 promise 仅限解析器。在其他解析器中,promise 可能根本不会被使用,当 jwt 验证失败时,拒绝将不会被处理。 (另外,如果解析器是异步执行的,promise 可能会在它们处理它之前被拒绝)。
相反,whole context initialisation应该异步完成,返回一个带有用户详细信息的上下文对象的 promise 。这意味着请求甚至在开始执行查询之前就会失败:

const server = new ApolloServer({ 
typeDefs,
resolvers,
context: ({ req }) => {
if (req.headers.authorization) {
const token = req.headers.authorization.split(' ')[1];
return new Promise((resolve, reject) => {
jwt.verify(token, getKey, options, (err, decoded) => {
if (err) reject(err);
else resolve(decoded);
});
}).then(authUser => {
if (authUser) return { authUser };
// else return {};
});
// .catch(err => { … }) - you may chose to ignore verification failure,
// and still return a context object (without an `authUser`)
}
// else return {}; - when not sending the header, no token will be checked at all
},
introspection: true,
playground: true
});
// a graphql resolver that checks for the authUserObj
addUser: async (parent, args, {authUserObj}) => {
if (!authUserObj) { // you might also want to check specific claims of the jwt
throw new AuthenticationError('You must be logged in to do this');
}
const response = await User.create(args);
return response;
}

关于javascript - 将 catch block 添加到 Promise 会返回待处理而不是被拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64129487/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com