为什么在 try 已经处理响应时调用我的 catch 块?

Why is my catch block being called when try is already handling the response?

我知道它与;第二次设置 header 无效,但我的应用程序在发送第一个响应后甚至没有发送另一个请求就崩溃了。

当应用程序崩溃时,控制台指示检查代码的 catch 块。

我主要关心的是为什么在执行没有错误的情况下执行会进入catch块,因为我只想检查用户是否存在,据我了解结果应该是一样的,不管是什么我们检查的次数。如果我尝试添加一个已经存在的用户,这是正确的,我得到输出:

if (user.rows.length !== 0) {
    res.status(400).json("User already exists");
}

那为什么在发送 json 后调用我的 catch 块?我已经尝试更改响应状态代码并将其更改为 res.status(401).send("User already exists"); 也给出了相同的错误,但是一旦我只更改状态并且不发送任何消息服务器就可以正常使用 res.status(401),为什么我的 catch 块在使用 json/send??

发送响应后被调用

我可以在此处采用什么更好的方法?

这是代码:

try {
    // extract data from request body
    const { user_name, user_email, user_password } = req.body;

    // check if user already exists
    const user = await pool.query("SELECT * FROM users WHERE user_email = ", [user_email]);
    // console.log(typeof user); returns object
    // console.log(user.rows);
    if (user.rows.length !== 0) {
        res.status(400).json("User already exists");
    }

    // bcrypt the user password
    const saltRound = 10; // Try randomising the salt rounds
    const salt = await bcrypt.genSalt(saltRound);
    const bcryptPassword = await bcrypt.hash(user_password, salt); // encrypted password

    // insert user into database
    const newUser = await pool.query("Insert INTO users (user_name, user_email, user_password) VALUES (, , ) RETURNING *", [user_name, user_email, bcryptPassword]);

    res.json(newUser.rows[0]);
} catch (error) {
    console.error(error.message);
    res.status(500).send("Server Error");
}

控制台错误:

Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

您收到此错误是因为您没有检查 else 块。检查 if 语句后,它会停止并尝试执行其余代码。您的 catch 块未执行,因为如果执行了,您将获得 500。尝试执行如下代码 -

if (user.rows.length !== 0) {
        res.status(400).json("User already exists");
    }else{

    // bcrypt the user password
    const saltRound = 10; // Try randomising the salt rounds
    const salt = await bcrypt.genSalt(saltRound);
    const bcryptPassword = await bcrypt.hash(user_password, salt); // encrypted password

    // insert user into database
    const newUser = await pool.query("Insert INTO users (user_name, user_email, user_password) VALUES (, , ) RETURNING *", [user_name, user_email, bcryptPassword]);

    res.json(newUser.rows[0]);
    }

您不能同时执行两个响应。希望这能帮助您解决问题。

根据您的代码,您正在使用错误的方法处理 if 块。在 NodeJs 中,因为它本质上是异步的,所以它永远不会像您预期的那样终止。在 if 块中添加 return。

 if (user.rows.length !== 0) {
        return res.status(400).json("User already exists");
 }

它将return响应并中断进一步代码的执行。根据您的代码,它正在执行新用户创建代码并尝试创建新用户,该新用户已经存在于 sql 抛出错误的位置并转到 catch 块。然后再次尝试发送新的错误响应,它给你 ERR_HTTP_HEADERS_SEND。 根据最佳实践,始终首先处理错误情况,因此它不会创建 if-else 阶梯。