<commit_before>import React from 'react';
import LoginForm from './LoginForm.jsx';
import {storeTokens} from '../helpers';

export default class Login extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      loginError: null,
      isSubmitting: false
    };
  }

  onBeginSubmit() {
    this.setState({
      isSubmitting: true
    });
  }

  onEndSubmit() {
    this.setState({
      isSubmitting: false
    });
  }

  async onSubmit(data) {
    this.onBeginSubmit();
    await this.onSubmitImpl(data);
  }

  async onSubmitImpl(data) {
    const email = data.formData.email;
    const pw = data.formData.password;

    let tokens;
    try {
      tokens = await this.props.api.login(email, pw);
    } catch (err) {
      this.onLoginError(err);
      return Promise.resolve();
    }

    try {
      await this.props.api.frontendLogin(email, pw);
      this.onEndSubmit();
      this.onLoginSuccess(tokens);
    } catch (err) {
      this.onEndSubmit();
      this.onLoginError(err);
    }
  }

  onLoginSuccess(tokens) {
    storeTokens(tokens);
    this.props.history.push('/r/select-role');
  }

  onLoginError(err) {
    this.setState({
      loginError: err.message
    });
  }

  render() {<commit_msg>Add error handling to login<commit_after>import React from 'react';
import LoginForm from './LoginForm.jsx';
import {storeTokens} from '../helpers';

export default class Login extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      loginError: null,
      isSubmitting: false
    };
  }

  onBeginSubmit() {
    this.setState({
      isSubmitting: true
    });
  }

  onEndSubmit() {
    this.setState({
      isSubmitting: false
    });
  }

  async onSubmit(data) {
    this.onBeginSubmit();
    await this.onSubmitImpl(data);
  }

  async onSubmitImpl(data) {
    const email = data.formData.email;
    const pw = data.formData.password;

    let tokens;
    try {
      tokens = await this.props.api.login(email, pw);
    } catch (err) {
      this.onLoginError(err);
      this.onEndSubmit();
      return Promise.resolve();
    }

    try {
      await this.props.api.frontendLogin(email, pw);
      this.onEndSubmit();
      this.onLoginSuccess(tokens);
    } catch (err) {
      this.onEndSubmit();
      this.onLoginError(err);
    }
  }

  onLoginSuccess(tokens) {
    storeTokens(tokens);
    this.props.history.push('/r/select-role');
  }

  onLoginError(err) {
    let message = err.message;
    if (err.response && err.response.status === 400) {
      message = this.props.i18next.t('client.login.error_login');
    }
    this.setState({
      loginError: message
    });
  }

  render() {
{'fraction_non_alphanumeric': 0.13578869047619047, 'fraction_numerical': 0.0018601190476190475, 'mean_word_length': 2.556878306878307, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2994630', 'n_tokens_mistral': 894, 'n_tokens_neox': 879, 'n_words': 166}