Как обработать несколько ошибок в цепочке обещаний? - PullRequest
0 голосов
/ 29 мая 2018

Я использую AWS Amplify для аутентификации и Stripe для оплаты, чтобы создать страницу регистрации.

ПРОБЛЕМА: я не могу найти способ объединить проверки для раздела электронной почты и пароля (из AWS Amplify)с разделом информации о платеже (из Stripe).

Мой текущий код создает токен Stripe и API вызова (с действительной информацией о платеже), а затем обрабатывает сообщение об ошибке из userSignupRequest, которое обрабатывает поля электронной почты и пароль.

Как проверить адрес электронной почты и пароль с информацией об оплате, а затем создать учетную запись в AWS и Stripe?

enter image description here

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

  })

1 Ответ

0 голосов
/ 30 мая 2018

Кажется, у нас очень похожий стек.Мое решение было обрабатывать все на стороне сервера.Вам нужно будет дать вашим лямбда-функциям соответствующие разрешения IAM для доступа к Cognito.Код ниже немного длинный.Я использую async / await , который действительно помогает мне разобраться.Вам нужно будет использовать Lambda с узлом 8, чтобы использовать async / await.

Я проверяю, что все соответствует правильному формату на стороне клиента (т.е. электронные письма - это действительно электронные письма, пароли - правильной длины).Я понял, что единственная ошибка, которая может появиться - это ошибка «существующего пользователя» от Cognito.Идея такова: проверьте, существует ли пользователь, прежде чем пытаться зарегистрировать человека с помощью Stripe.Нет способа «проверить», действительна ли кредитная карта пользователя с Stripe.Это все или ничего.Если он действителен, он пройдет, если нет, вы получите ошибку.Если это произойдет, вы можете зарегистрировать пользователя в Cognito, зная, что вы не должны получить ошибку (вы проверили адрес электронной почты и пароль на стороне клиента и знаете, что его использование еще не существует).

Для справки, вот aws-sdk для 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;
};
...