如何处理承诺链中的多个错误? [英] How to handle multiple errors in promise chain?

查看:110
本文介绍了如何处理承诺链中的多个错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用AWS Amplify进行身份验证,使用Stripe进行付款以创建注册页面。

I'm using AWS Amplify for authentication and Stripe for the payment to create sign up page.

问题:我找不到合并验证的方法电子邮件和密码部分(来自AWS Amplify),带有付款信息部分(来自Stripe)。

PROBLEM: I can't find a way to combine validations for Email and password section(from AWS Amplify) with payment info section(from Stripe).

我当前的代码创建一个Stripe令牌并调用API(带有有效的付款信息)然后处理来自 userSignupRequest 的错误消息,它负责处理电子邮件和密码字段。

My current code creates a Stripe token and call API(with valid payment info) then handles the error message from userSignupRequest which takes care of email and password fields.

如何验证电子邮件和带有付款信息的密码然后在AWS和Stripe中创建帐户?

How do I validate the email and password with payment info then create account in AWS and Stripe?

  // Stripe payment process
  this.props.stripe.createToken(
    {
      email: this.state.email
    }
  ).then(result => {
    // PROBLEM: Form server validation from Stripe
    if(result.error){
      return this.setState({ errors: { errorMsg: result.error.message }, isLoading: false })
    }

    // if success, create customer and subscription with result.token.id
    const apiName = 'NameOfAPI';
    const path = '/stripe/signup';
    let myInit = {
      body: {
        "stripeToken": result.token.id,
        "email": this.state.email
      }
    }

    API.post(apiName , path, myInit).then(reponse => {
      this.props.userSignupRequest(this.state.email, this.state.password, reponse).then(user => {
        this.setState({
          confirmAccount: true,
          isLoading: false,
          userEmail: this.state.email,
          errors: {}
        })
        this.props.history.push('/signup#confirm-account')
      }).catch(err => {
        // PROBLEM: Form server validation 
        this.setState({ errors: { errorMsg: err.message }, isLoading: false })
      })

    }).catch(err => {
      console.log(err)
      this.setState({ errors: { errorMsg: err }, isLoading: false })
    });

  })


推荐答案

它好像我们有一个非常相似的堆栈。我的解决方案是处理服务器端的所有事情。您需要为lambda函数提供适当的IAM权限才能访问Cognito。下面的代码有点长。我使用 async / await 为我清理事情。你需要使用带有节点8的Lambda来使用async / await。

It seems like we have a very similar stack. My solution was to handle everything server-side. You'll need to give your lambda functions the appropriate IAM permissions to access Cognito. The code below is a little long. I use async/await, which really cleans things up for me. You'll need to use Lambda with node 8 to use async/await though.

我验证一切都符合正确的格式客户端(即电子邮件真的是电子邮件,密码是正确的长度)。我意识到唯一可能出现的错误是来自Cognito的现有用户错误。这个想法是:在尝试使用Stripe签名此人之前测试用户是否存在。如果用户的信用卡对Stripe有效,则无法测试。这是全有或全无。如果它有效则会通过,如果没有,你会收到错误。如果它通过,您可以使用Cognito注册用户,知道您不应该收到错误(您已经验证了客户端的电子邮件和密码,并且您知道该用户尚未存在)。

I validate that everything matches the right format client-side (i.e. emails are really emails, passwords are the right length). I realized the only error that could come up is an "existing user" error from Cognito. The idea is: test if the user exists before you attempt to sign the person up with Stripe. There's no way to "test" if the user's credit card is valid with Stripe. It's all or nothing. If it's valid it will go through, if not, you'll get an error. If it goes through, you can then sign up the user with Cognito, knowing you should not get an error (you've validated the email and password client-side and, you know the use doesn't already exist).

作为参考,这里是 aws-sdk for cognito

const AWS = require('aws-sdk');
const cognito = new AWS.CognitoIdentityServiceProvider({
  region: "region",
  userPoolId: "cognito_user_pool_id",
});

module.exports.signUpUser = (payload) => {
  const usernamePayload = {
    UserPoolId: "cognito_user_pool_id",
    Username: payload.email,
  };

  // I use emails for usernames.

    new Promise((resolve, reject) => {
      cognito.adminGetUser(usernamePayload, (error, response) => {
        if (error && error.code === 'UserNotFoundException') {
          resolve(false);
        } else if (error) {
          reject(error);
        } else {
          // if adminGetUser doesn't fail, it means the username exists
          resolve(true);
        }
      });
    }).then((usernameExists) => {
      if (!usernameExists) {
        // run stripe API stuff
        // always run before sign up below to catch stripe errors
        // and return those errors to client
        // before you sign up the user to Cognito

        // since you've already verified the user does not exist
        // it would be rare for an error to come up here
        // as long as you validate passwords and emails client-side
        const signUpPayload = {
          ClientId: "cognito_user_pool_client_id",
          Username: payload.email,
          Password: payload.password,
          UserAttributes: [
            {
              Name: 'email',
              Value: payload.email,
            },
          ],
        };

          new Promise((resolve, reject) => {
            cognito.signUp(signUpPayload, (error, response) => {
              if (error) {
                reject(error);
              } else {
                resolve(response);
              }
            });
          }).catch((error) => {
            // you should hopefully encounter no errors here
            // once you get everything setup correctly
            console.log(error);
          })
      } else {
        // means username already exists, send error to client
        // saying username exists
      }
    }).catch((error) => {
      // may want to dispatch this error to client
      console.log(error);
    });

  return null;
};

这篇关于如何处理承诺链中的多个错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆