如何解决未处理的承诺拒绝?

Posted

技术标签:

【中文标题】如何解决未处理的承诺拒绝?【英文标题】:How to solve unhandeled promise rejections? 【发布时间】:2021-09-27 00:58:33 【问题描述】:

错误: UnhandledPromiseRejectionWarning: SyntaxError: Unexpected token o in JSON at position 1 我正在制作一个 MERN 堆栈应用程序,在 Frontend 我有注册表单,下面给出的是它的 POST 方法。

const onSignUp = async (e) =>             
        e.preventDefault();
        try 
            const body = 
                username,  
                email, 
                password, 
                firstname, 
                lastname, 
                country_code, 
                phone_no,  
                address, 
                city, 
                state, 
                country
            ;
            console.log(typeof(JSON.stringify(body)));                        
            const response = await fetch("http://localhost:5000/api/user/create",
                method : "POST",
                headers: "Content-Type" : "application/json",
                body: JSON.stringify(body)
            );            
            console.log(response);
        
        catch (err) 
            console.error(err.message);
        
    

考虑主 index.js 文件中的 api/user ,此路由在 user.js 文件中创建。 而在 Backend 我有/create 路由如下:-

router.post('/create', async (req, res) => 
    const body = JSON.parse(req.body)
    console.log('backend'+typeof(req.body));
    try        
        const username, email, password, firstname, lastname, country_code, phone_no,  address, city, state, country = req.body;
        const salt = await bcrypt.genSalt(10);
        const hashed_password = await bcrypt.hash(password, salt);
        const newUser = await pool.query(
            "INSERT INTO User_ (username, email, password, firstname, lastname, country_code, phone_no,  address, city, state, country) VALUES ($1, $2, $3, $4,$5, $6, $7, $8, $9, $10, $11) RETURNING user_id, username"
            [username, email, hashed_password, firstname, lastname, country_code, phone_no,  address, city, state, country]
        );
        res.status(201).send(newUser.rows[0]);
    
    catch(err)
        console.log("Error : ", err);
    
)

【问题讨论】:

【参考方案1】:

我认为这有两层。

首先,async 函数总是返回承诺。如果在 async 函数中抛出错误,它会拒绝函数返回的承诺。在您的路线处理程序中,您有

const body = JSON.parse(req.body)

async 函数的顶层。这意味着任何抛出解析 JSON 的错误都将是未处理的拒绝。

您可能希望将该行移入 try/catch 以便处理,因为 Express 不会对您返回的承诺做任何事情。 但是,请看下一条。

其次,您的错误消息是您在调用 JSON.parse 时遇到的典型错误,该错误 已经 被解析并且是一个对象,因为 JSON.parse 将其参数转换为字符串,并且对于普通对象,您得到的字符串是 "[object Object]" - 请注意位置 1 处的 o(从 0 开始)。

我怀疑您安装了已经为您解析 JSON 的中间件,所以您根本不想进行 JSON.parse 调用。只需使用req.body 上的对象即可。

【讨论】:

如果我删除 json.parse 因为它已经被解析,那么它会给我类似的错误:TypeError: Client was passed a null or undefined query @SMEETKOTHARI - 你在路由器中安装了 JSON 中间件吗?例如,express.json(). @SMEETKOTHARI - 然后我怀疑问题不在于 JSON,fetch 看起来正确,express.json() 没有损坏。我建议在进行解构的行上放置一个断点(是的,您可以调试 Node.js 服务器代码,请参阅文档中的 --inspect-brk)并查看它失败的地方。错误消息听起来像是来自解构后的某些东西。添加JSON.parse 只是通过早期失败来隐藏问题。 我重写了 index,js 以及我的路由和错误消失了,Thnx 寻求帮助 @T.J.Crowder

以上是关于如何解决未处理的承诺拒绝?的主要内容,如果未能解决你的问题,请参考以下文章

如何修复可能的未处理承诺拒绝(id:0)?以及如何修复无法读取未定义的属性“导航”?

未处理的承诺警告。如何解决?

如何在 Node.js expressjs 的异步对象方法中处理未处理的承诺拒绝?

拒绝承诺时如何解决 UnhandledPromiseRejectionWarning

处理多个承诺拒绝[重复]

无法读取未定义和未处理的承诺拒绝的属性“捕获”