React-stripe-elements: this.props.stripe.createToken({}).then().catch(err) is not catching card validation errors

Created on 28 Aug 2018  路  4Comments  路  Source: stripe/react-stripe-elements

Summary

this.props.stripe.createToken({name,address_line1, etc}) .then (result=>{console.log(result)}) .catch((err)=> {console.log(err)});

does not catch any form validation error. instead it returns an error object within the .then statement in the form of result.error.

Is this behaving as expected? I can work around it by putting my error handling in the .then(result) but it seems silly to me.

Most helpful comment

Yep, this is as expected!

We explicitly want you to handle the errors when the Promise resolves. Since the shape of result can be either {error: {...}} or {token: {...}}, you must condition over it and explicitly handle the error. If we had just thrown an error, many developers may not add a .catch() and ignore the error altogether.

Another reason for this behavior is that it makes using async/await syntax easier. Currently you can do:

const {error, token} = await this.props.stripe.createToken(...);
if (error) {
 // Handle error
} else {
  // Charge token...
}

If we had thrown an error, you would have to use try-catch, which is less than elegant, and also suffers from the problem that many developers may forget to handle the error.

try {
  const token = await this.props.stripe.createToken(...);
} catch (e) {
  // Handle error
}

Our belief is that this approach makes for a safer, more explicit integration. If you have feedback though, please let us know!

(Note also that this matches the behavior of another popular Promise based API, fetch().)

All 4 comments

https://stripe.com/docs/stripe-js/reference

just found the documentation i guess it is behaving as expected

Yep, this is as expected!

We explicitly want you to handle the errors when the Promise resolves. Since the shape of result can be either {error: {...}} or {token: {...}}, you must condition over it and explicitly handle the error. If we had just thrown an error, many developers may not add a .catch() and ignore the error altogether.

Another reason for this behavior is that it makes using async/await syntax easier. Currently you can do:

const {error, token} = await this.props.stripe.createToken(...);
if (error) {
 // Handle error
} else {
  // Charge token...
}

If we had thrown an error, you would have to use try-catch, which is less than elegant, and also suffers from the problem that many developers may forget to handle the error.

try {
  const token = await this.props.stripe.createToken(...);
} catch (e) {
  // Handle error
}

Our belief is that this approach makes for a safer, more explicit integration. If you have feedback though, please let us know!

(Note also that this matches the behavior of another popular Promise based API, fetch().)

@atty-stripe thank you so much for taking the time to explain that async/await decision! 馃憤 馃挴

This surprised me. I end up with Stripe calls being the only code that handles errors within the resolution of a promise as opposed to the catch, but oh well 馃憤

try {
  const { error, token } = await this.stripe.createToken(cardNumber)
  if (error) throw error
  ... 
} catch (err) {
  this.error = err.message
}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Thebarda picture Thebarda  路  5Comments

kavsingh picture kavsingh  路  4Comments

cleemputc picture cleemputc  路  5Comments

max-favilli picture max-favilli  路  5Comments

Dasyel picture Dasyel  路  4Comments