最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

如何在出错时从异步函数返回

网站源码admin39浏览0评论

如何在出错时从异步函数返回

如何在出错时从异步函数返回

 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();
}

这完成了以下事情:

  1. 它直接和单独地处理来自
    conn.getconnection()
    的拒绝,因为除了发送错误响应之外,您不想在该错误之后执行任何代码。
  2. 它不会混合
    await
    .then()
    .catch()
    。为任何给定的功能选择另一种风格,因为当您混合使用它们时,流程控制会变得混乱和混乱。
  3. 它在所有可能的错误情况下都对请求发送适当的响应。
  4. 确保在检索数据库连接的所有可能错误路径中调用
    conn.closedb()

注意:您没有显示

query
变量的来源,但由于它被直接提供给您的
.updateOne()
方法,您必须确保它是安全的。如果它直接来自表单发布或查询字符串,那么您可能需要对其进行清理以确保它是安全的,这样任何可能的输入都不会对您的数据库进行意外操作。

发布评论

评论列表(0)

  1. 暂无评论