函数返回"/>
如何在出错时从异步函数返回
await conn.getconnection().catch((error)=>{
console.log("No connection");
return;
});
let collection = conn.getdb().collection(type);
async function getconnection(){
client = new MongoClient(url);
await client.connect();
db = client.db(dbName);
console.log("Connected to db");
}
以上代码用于连接mongodb数据库。但是在不连接到数据库时,异步函数不会返回并且集合正在尝试执行导致错误。我如何停止执行函数并返回父函数?
注意:-该功能在数据库运行时正常工作。但是当不运行应用程序崩溃时。我希望错误被捕获而不是崩溃。
错误是
No connection
let collection = conn.getdb().collection(type);
^
TypeError: Cannot read properties of undefined (reading 'collection')
编辑:-
await conn.getconnection().catch(console.error);
let collection = conn.getdb().collection(type);
console.log("Entered collection");
await collection.updateOne(query,{$set : newdata})
.then(()=>{
res.send("Done");
})
.catch((error)=>{
console.log(error);
res.send("Error");
})
conn.closedb();
完全添加 catch 的问题是,如果连接成功后发生连接错误,则连接不会关闭。所以再次调用该函数时会发生错误。
但我无法使用 finally 关闭连接,因为如果
connect()
函数发生错误,则没有连接可以关闭。所以错误发生在最后
回答如下:
首先,这段代码有点乱,因为你是通过“副作用”来编码的。你调用像
getConnection()
这样的东西,它显然有一个副作用,它在一些更高的范围内设置了几个变量(client
和 db
)。这些不是对象的实例变量。它们不会从函数返回,以便调用者可以使用它们。它们被塞入一些更高范围的变量中。这意味着如果第二个传入请求在第一个调用者完成使用它之前调用getconnection()
,那么您将覆盖那些更高级别的变量,并且第一个值可能不会像他们应该的那样被关闭或释放。这是一个必须解决的单独问题。
再次强调,由于您在这里只显示了一小段代码上下文,我们无法就如何最好地解决此问题提出更大的建议。可能你应该做像
getConnection()
这样的东西,只是返回连接而不是将它填充到任何地方,然后让调用者使用他们获得的值并自己释放/关闭它。然后,多个调用者可以调用getConnection()
,没有人会践踏对方的价值。但是,还有其他设计,其中连接被缓存/共享或强制序列化。 您还需要修复此问题,因为您可能会遇到并发问题。
不管怎样,回到你问的主要问题。您在此处获取连接的功能:
async function getconnection(){
client = new MongoClient(url);
await client.connect();
db = client.db(dbName);
console.log("Connected to db");
}
如果 client.connect()
失败,将拒绝。因此,此函数的调用者需要正确处理该拒绝。您显示调用该函数的唯一地方是您记录错误的地方,但允许继续执行代码。你需要正确地“处理”那个错误。
await conn.getconnection().catch(console.error);
let collection = conn.getdb().collection(type);
console.log("Entered collection");
await collection.updateOne(query,{$set : newdata})
.then(()=>{
res.send("Done");
})
.catch((error)=>{
console.log(error);
res.send("Error");
})
conn.closedb();
我建议这样重写:
try {
await conn.getconnection();
} catch(e) {
console.error('error getting database connection', e);
res.status(500).send('Error connecting to database');
return;
}
try {
const collection = conn.getdb().collection(type);
// may need to sanitize the query variable to make sure it's safe
await collection.updateOne(query, { $set: newdata });
res.send("Done");
} catch(e) {
console.error(e);
res.status(500).send("Database error");
} finally {
conn.closedb();
}
这完成了以下事情:
- 它直接和单独地处理来自
的拒绝,因为除了发送错误响应之外,您不想在该错误之后执行任何代码。conn.getconnection()
- 它不会混合
和await
和.then()
。为任何给定的功能选择另一种风格,因为当您混合使用它们时,流程控制会变得混乱和混乱。.catch()
- 它在所有可能的错误情况下都对请求发送适当的响应。
- 确保在检索数据库连接的所有可能错误路径中调用
。conn.closedb()
注意:您没有显示
query
变量的来源,但由于它被直接提供给您的 .updateOne()
方法,您必须确保它是安全的。如果它直接来自表单发布或查询字符串,那么您可能需要对其进行清理以确保它是安全的,这样任何可能的输入都不会对您的数据库进行意外操作。
更多推荐
如何在出错时从异步函数返回
发布评论