繁体   English   中英

如何在客户端捕获拒绝 promise 的错误?

[英]How to catch error of rejected promise on client side?

如果用户尝试使用现有帐户注册,我试图让我的服务器拒绝signup请求。 但是,我似乎无法正确拒绝它并将错误消息传递给我的客户端。

//server.js

app.post('/signup', (req, res) => {
  const email = req.body.email
  const plainTextPassword = req.body.password;

  //check if user already exists 
  User.find({ email: email }, (err, existingUser) => {
    //account doesnt exist
    if (existingUser.length === 0) {
      bcrypt.hash(plainTextPassword, saltRounds, async (err, hash) => {
        try {
          const user = new User({
            email: email,
            password: hash
          });
          let result = await user.save();
          if (result) {
            res.send(result)
          }

        } catch (e) {
          res.send(e);
        }
      })
    } else {
      //notify user that account exists
      return Promise.reject(new Error('Account already exists'))
    }
  })

})
//reduxSlice.js
export const signup = createAsyncThunk(
    'userAuth/signup',
    async (payload, thunkAPI) => {
        const { email, password } = payload
        try {
            const result = await fetch(
                signupPath, {
                mode: 'cors',
                credentials: 'include',
                method: "post",
                body: JSON.stringify({ email, password }),
                headers: {
                    'Content-Type': 'application/json'
                }
            }
            )
            return result.json()
        } catch (error) {
            console.log(error) //this line executes
        }

    }
)

从我的 reduxdev 工具中,即使我从服务器拒绝了它,我的signup仍然完成。 此外,我的服务器在一次尝试后崩溃,这让我怀疑存在未捕获的错误。

客户端只接收您使用res.send()next(err)执行的操作,然后调用res.send() Promise 仅对服务器是本地的,而不是被发送回客户端的东西。

在您的原始代码中,我建议您仅使用基于 Promise 的异步操作,然后您可以throw您的代码,在一个地方捕获所有错误,然后从那里将错误发送回客户端。

class ServerError extends Error {
    constructor(msg, status) {
        super(msg)
        this.status = status;
    }
}

app.post('/signup', (req, res) => {
    try {
        const email = req.body.email
        const plainTextPassword = req.body.password;

        //check if user already exists
        const existingUser = await User.find({ email: email });
        //account doesnt exist
        if (existingUser.length !== 0) {
            throw new ServerError('Account already exist', 403);
        }
        const hash = await bcrypt.hash(plainTextPassword, saltRounds);
        const user = new User({
            email: email,
            password: hash
        });
        const result = await user.save();
        res.send(result);
    } catch (e) {
        if (!e.status) e.status = 500;
        console.log(e);
        res.status(e.status).send({err: e.message});
    }
});

然后,在使用fetch()的客户端代码中,您需要检查result.ok以查看是否返回 2xx 状态。 fetch()仅在与目标主机的网络连接失败时才会拒绝。 如果连接成功,即使返回错误状态, fetch() promise 也会解析。 您必须检查result.ok以查看您是否获得 2xx 状态。

//reduxSlice.js
export const signup = createAsyncThunk(
    'userAuth/signup',
    async (payload, thunkAPI) => {
        const { email, password } = payload
        try {
            const result = await fetch(
                signupPath, {
                mode: 'cors',
                credentials: 'include',
                method: "post",
                body: JSON.stringify({ email, password }),
                headers: {
                    'Content-Type': 'application/json'
                }
            });
            // check to see if we got a 2xx status success
            if (!result.ok) {
                throw new Error(`signup failed: ${response.status}`);
            }
            return result.json()
        } catch (error) {
            console.log(error) //this line executes
        }

    }
)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM