Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use more user friendly errors when choosing default fund for Wallet #7929

Merged
merged 14 commits into from
Mar 10, 2022

Conversation

mountiny
Copy link
Contributor

@mountiny mountiny commented Feb 28, 2022

Related to https://github.com/Expensify/Web-Expensify/pull/33132

And related to small backend change where I emphasize the error messages need to be updated in frontend too if changed in backend https://github.com/Expensify/Auth/pull/6477

Details

We have only been showing a generic error when setting a default fund for Expensify Wallet has failed. This change handles all the possible error and gives the user better feedback when it fails. Unfortunately, for most of these errors the users cannot do much on their own, but knowing the specific error message can help the support to identify the next steps to fix it.

Fixed Issues

$ #7521

Tests

  • Verify that no errors appear in the JS console

To test all the specific errors would be hard. We can leave this for Applause as they reported this problem and we are only making the error messages a bit more helpful.

Prerequisite: Set the VBA in testing account (But make sure it is not in OPEN state)

  1. Launch the app
  2. Log in expensifail account (when locally testing any account which has Wallet)
  3. Go to Setting - Payment
  4. Tap on some card
  5. Tap Set a default payment
  6. Enter correct password
  7. Tap Make Default payment method
  8. Make sure there is more specific like this.

image

PR Review Checklist

Contributor (PR Author) Checklist

  • I made sure to pull main before submitting my PR for review
  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I clearly indicated the environment tests should be run in (Staging vs Production)
  • I wrote testing steps that cover success & fail scenarios (if applicable)
  • I ran the tests & they passed on all platforms
  • I included screenshots or videos for tests on all platforms
  • I verified there are no console errors related to changes in this PR
  • I followed proper code patterns (see Reviewing the code)
    • I added comments when the code was not self explanatory
    • I put all copy / text shown in the product in all src/languages/* files (if applicable)
    • I followed proper naming convention for platform-specific files (if applicable)
    • I followed style guidelines (in Styling.md) for all style edits I made
  • I followed the guidelines as stated in the Review Guidelines

PR Reviewer Checklist

  • I verified the Author pulled main before submitting the PR
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the testing environment is mentioned in the test steps
  • I verified testing steps cover success & fail scenarios (if applicable)
  • I verified tests pass on all platforms & I tested again on all platforms
  • I checked that screenshots or videos are included for tests on all platforms
  • I verified there are no console errors related to changes in this PR
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified comments were added when the code was not self explanatory
    • I verified any copy / text shown in the product was added in all src/languages/* files (if applicable)
    • I verified proper naming convention for platform-specific files was followed (if applicable)
    • I verified style guidelines were followed
  • I verified that this PR follows the guidelines as stated in the Review Guidelines

QA Steps

  • Verify that no errors appear in the JS console

Prerequisite: Set the VBA in testing account

  1. Launch the app
  2. Log in expensifail account
  3. Go to Setting - Payment
  4. Tap on Verified Account
  5. Tap Set a default payment
  6. Enter correct password
  7. Tap Make Default payment method
  8. One of these errors should show:
  • 'There was an error setting this bank account as your default payment method.',
  • 'This bank account is temporarily suspended.',
  • 'There was an error setting this card as your default payment method.',
  • 'Something went wrong. Please chat with Concierge for further assistance.',

Tested On

  • Web
  • Mobile Web
  • Desktop
  • iOS
  • Android

Screenshots

Web

image

since this is only API error handling change, I have not tested it on all platforms as there is not expectation of change.

@mountiny mountiny requested a review from a team as a code owner February 28, 2022 00:51
@mountiny mountiny self-assigned this Feb 28, 2022
@MelvinBot MelvinBot requested review from madmax330 and removed request for a team February 28, 2022 00:52
Comment on lines 369 to 374
noAccountToLink: 'Something went wrong. Please, contact Concierge.',
invalidWallet: 'Your Wallet is currently suspended. Reach out to Concierge for help.',
notOwnerOfBankAccount: 'We couldn\'t link this bank account to your Wallet. Please, reach out to Concierge for help.',
invalidBankAccount: 'This bank account is temporarily suspended. Reach out to Concierge for help.',
notOwnerOfFund: 'We couldn\'t link this fund to your Wallet. Reach out to Concierge for help.',
invalidFund: 'This fund is temporarily suspended. Reach out to Concierge for help.',
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waiting for translations.

@mountiny mountiny changed the title Use more user friendly errors when choosing default fund for Wallet [WIP translations] Use more user friendly errors when choosing default fund for Wallet Feb 28, 2022
@kevinksullivan
Copy link
Contributor

kevinksullivan commented Mar 2, 2022

Sorry @mountiny I just caught up to this issue after OOO. We do not mention the word "Wallet" in product anywhere, so can we update the error message copy to avoid doing so?

Also, what is a "fund"? I don't know what that means or how to fix it, so I think that will be confusing to users.

Here are my suggestions for the first 4 (will propose something for the last two once I know what "fund" means):

error message Explanation
405 No account to link to wallet Something went wrong. Please chat with concierge for further assistance. If this happens something is wrong in the App so we should definitely report a bug, this is not a mistake on user's side.
405 Invalid wallet account We were unable to set this bank account as your default payment method. Please reach out to concierge for help. User's wallet is not in Open state and most likely that means the state is Suspended. They would reach out to Concierge to have this sorted out.
401 Wallet owner does not own linked bank account We were unable to set this bank account as your default payment method. Please reach out to concierge for help. This should not happen very often and it would indicate some problem in users account or some bad actor trying to link someone else's bank account to their wallet.
405 Attempting to link an invalid bank account to a wallet This bank account is temporarily suspended. Please reach out to concierge for help. The bank account they trying to use is most likely in suspended state and Concierge should look into why.
401 Wallet owner does not own linked fund We were unable to set this card as your default payment method. Please reach out to concierge for help. This should not happen very often and it would indicate some problem in users account or some bad actor trying to link someone else's card to their wallet.
405 Attempting to link an invalid fund to a wallet We were unable to set this card as your default payment method. Please reach out to concierge for help. The fund they trying to use is most likely in suspended state and Concierge should look into why.

@mountiny
Copy link
Contributor Author

mountiny commented Mar 2, 2022

@kevinksullivan Oh, thank you for heads up, I think these should still be in beta so users should not see it, but better safe than sorry. cc @rosegrech as you helped with the translations.

I think funds are related to cards in this case, but I am not sure if it can be more things. There are VBAs and cards which can be used to top up the Wallet, right? @madmax330 should be able to shed more light on this too, thank you 🙇

@kevinksullivan
Copy link
Contributor

Ahh got it ok, yeah those are likely debit cards then. I updated the table to incorporate suggestions for those as well. Basically I suggest we:

  1. Drop mention of Wallet
  2. Not explain that a card or account is Suspended if the user cannot do anything about it. If the best thing they can do is reach out to us for help, and they're either a bad actor or someone that has to reach out to us, then we just instruct them to talk to concierge.

@mountiny
Copy link
Contributor Author

mountiny commented Mar 2, 2022

Sounds good to me, I will just wait for @rosegrech if she has anything to add here as she has helped with the original copy (but I suggested the Wallet and Suspended terms 😅 )

Gonna update the Spanish translation to HOLD

@rosegrech
Copy link

Thanks @kevinksullivan for jumping in. I did not realize about avoiding "wallet" so I updated our SO on copy.

Two quick overall things to note @vitHoracek

  • We should cap the "C' for "Concierge"
  • We try to use contractions when possible (not a big deal if we don't as it's proper ENG but just to be more casual speak. For example: use "We're" vs" We were", " I've" vs "I have", "Don't" vs "do not" etc/

@mountiny
Copy link
Contributor Author

mountiny commented Mar 3, 2022

Asked for translations in Slack. Thank you very much for your help on this!

@mountiny
Copy link
Contributor Author

mountiny commented Mar 8, 2022

I have updated the copy based on the discussion led here. For errors and notifications, we are trying to have a passive form. I have also reduced the number of messages as they have overlapped so now there are 3 messages and one deafult.

stitesExpensify
stitesExpensify previously approved these changes Mar 8, 2022
@stitesExpensify
Copy link
Contributor

Is this still WIP?

@mountiny
Copy link
Contributor Author

mountiny commented Mar 8, 2022

Still WIP, waiting for the Spanish translations as they were discussing more broadly what patterns to use in NewDot.

@mountiny mountiny changed the title [WIP translations] Use more user friendly errors when choosing default fund for Wallet Use more user friendly errors when choosing default fund for Wallet Mar 9, 2022
switch (error.message) {
case CONST.WALLET.ERROR.INVALID_WALLET:
case CONST.WALLET.ERROR.NOT_OWNER_OF_BANK_ACCOUNT:
Growl.show(Localize.translateLocal('paymentsPage.error.notOwnerOfBankAccount') + " " + Localize.translateLocal('common.conciergeHelp'), CONST.GROWL.ERROR, 5000);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per Ionatan suggestion, I have put the general Please contact Concierge message to separate translation so it can be reused. I have concatenated the two messages like this but I am not sure if there is a preference over doing this or using the `${foo} ${bar}` way.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, linter has answered this for me by throwing an error :)

@mountiny
Copy link
Contributor Author

mountiny commented Mar 9, 2022

@stitesExpensify @madmax330 This is now finally ready for a review! Thank you very much 🙇

Copy link
Contributor

@stitesExpensify stitesExpensify left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

Copy link
Contributor

@madmax330 madmax330 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, do we have to do all the steps mentioned in the OP or is that for contributor PRs?

@mountiny
Copy link
Contributor Author

No, I don't think that is necessary in this case. Also, it does not influence UI really so we should be good. Thank you very much for your reviews!

@mountiny mountiny merged commit 41bd789 into main Mar 10, 2022
@mountiny mountiny deleted the vit-improveWalletErrors branch March 10, 2022 11:43
@OSBotify
Copy link
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by @mountiny in version: 1.1.42-0 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

Growl.show(`${Localize.translateLocal('paymentsPage.error.invalidBankAccount')} ${Localize.translateLocal('common.conciergeHelp')}`, CONST.GROWL.ERROR, 5000);
return;
default:
Growl.show(Localize.translateLocal('paymentsPage.error.setDefaultFailure'), CONST.GROWL.ERROR, 5000);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyone know if it's possible for this API command promise method to land in this .catch() block?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exception is thrown and where?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh I think it's this weird code here that I am removing 😄

App/src/libs/API.js

Lines 182 to 187 in c26e415

if (response.jsonCode === 405 || response.jsonCode === 404) {
// IOU Split & Request money transactions failed due to invalid amount(405) or unable to split(404)
// It's a failure, so reject the queued request
queuedRequest.reject(response);
return;
}

I think most errors do not work this way and catch() should never do anything. No worries though just in the process of cleaning some stuff up.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is this one which we decided not to catch specifically as it should not happen but if it happens, the error message would need to be very general as the default already was.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes thanks I would like to know where the exception gets thrown in the JavaScript layer.

This issue has more details: https://github.com/Expensify/Expensify/issues/201109

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh interesting, I have first tried to handle it in the then case but it did not work for me, catch did. Not sure now why that is happening. Catch worked locally.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, thanks for the context! 🙌

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah it's because the promise is getting rejected which will trigger the .catch() block and would be similar to throwing an exception inside the .then() block. Kind of weird IMO because who knows how many API can throw these codes (or which may throw them in the future) and any that are not handled like you did here will crash the app.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, that is weird indeed. We should standardize this for sure.

@kbecciv
Copy link

kbecciv commented Mar 11, 2022

@mountiny We also experienced with App freezes when tried to set payment as default.

Image.from.iOS.6.MP4

@mountiny
Copy link
Contributor Author

@kbecciv hmm, that is odd. There was this issue #7869 which is exactly what you describe but it says it is fixed.

Can you confirm if this issue does not appear in production? If it happens in production too, we ould reopen the linked issue.

@kbecciv
Copy link

kbecciv commented Mar 14, 2022

@mountiny Issue appears in production as well.

Image.from.iOS.10.MP4

@mountiny
Copy link
Contributor Author

Thank you, I have reopened the linked issue!

@OSBotify
Copy link
Contributor

🚀 Deployed to production by @chiragsalian in version: 1.1.42-6 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants