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

Add try...catch to handle backup API failure #187

Merged
merged 3 commits into from
May 30, 2023

Conversation

renintw
Copy link
Contributor

@renintw renintw commented May 25, 2023

Fixes #182

This PR adds try...catch to handle backup API failure, rendering an error notice when the API doesn't work correctly.

Testing Steps

Go to account-status.js and comment out disabled={ ! backupCodesEnabled } on L78.

Scenario 1 - error.code === 'revalidation_required'

  1. Go to wp-content/plugins/two-factor/class-two-factor-core.php and remove the ! for the if condition on L1209.
    => if ( self::current_user_can_update_two_factor_options( 'save' ) ) {
  2. Go to /?screen=backup-codes and it's expected to have the same results as the screenshot below.

Local

revalidation_require

Sandbox

sandbox

Scenario 2 - other kinds of error

  1. Go to wp-content/plugins/two-factor/providers/class-two-factor-backup-codes.php and make it always throw an error on L295.
  2. Go to /?screen=backup-codes and it's expected to have the same results as the screenshot below - an error notice with an error message is shown.

other errors

Question

Do we want to show error messages dynamically on the front-end side, or alternatively, a certain error message like "Something went wrong, please seek assistance somewhere" could probably be displayed? As the error message like "Unable to enable recovery codes for this user." needs rephrasing a bit.

@renintw renintw self-assigned this May 25, 2023
@renintw renintw added bug Something isn't working ui Related to user interface priority: medium labels May 25, 2023
@renintw renintw force-pushed the fix/UI-not-handle-backup-api-fail branch from e0f8813 to c174901 Compare May 25, 2023 13:05
@renintw renintw added this to the Iteration 1 milestone May 25, 2023
@iandunn
Copy link
Member

iandunn commented May 25, 2023

show error messages dynamically ... or a certain error message like "Something went wrong, please seek assistance somewhere"

IMO it's best to show a specific message, because that helps us troubleshoot when someone reports a bug. Otherwise it can be harder to reproduce. I don't feel strongly, though.

Copy link
Member

@iandunn iandunn left a comment

Choose a reason for hiding this comment

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

Looks good overall 👍🏻

I think it's worth considering how revalidation is handled globally, but don't object to merging this either.

/>
{ error ? (
<>
{ error.code === 'revalidation_required' && <RevalidateModal /> }
Copy link
Member

Choose a reason for hiding this comment

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

🤔 I feel like it might get hard to maintain if every component has to be aware of revalidation, and build in logic to handle it. I wonder if we can do something that'd covers all components, without them having to be coupled to it? That's probably outside the scope of this PR, though.

I'd lean towards removing the revalidation stuff here, and just having the Notice to catch any kind of API error. I don't feel strongly, though.

If you decide to keep the revalidation, then I think it'd be good to return the user to the Backup Codes screen after they revalidate, so they can pick up where they left off. Otherwise I worry the flow might feel disjointed to them.

Copy link
Contributor

Choose a reason for hiding this comment

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

Agreed. I would lean towards using an apiFetch middleware: https://www.npmjs.com/package/@wordpress/api-fetch.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Tried using apiFetch middleware, but it didn't go well. Context couldn't be accessed in the middleware and the RevalidateModal needs it. I've tried several other ways and found out that one seems to work with a quick test. I'll open another PR for it after finishing the rest part of it. And for this PR, I'll remove the revalidation stuff here, and just have the Notice to catch any kind of API error. Thanks for bringing this up, it's a really good point. And thanks Steve for sharing a potential solution! 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

So I understand it correctly, you wanted to set the error within the app context and you couldn't?

Copy link
Contributor Author

@renintw renintw May 30, 2023

Choose a reason for hiding this comment

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

This is the branch I tried with apiFetch middleware, it's in the status that can be tested directly. I was trying to add a specific handler for revalidation using middleware, making it render the components we want if 'revalidation_required' !== error.code. However, as createRoot or any other way that dynamically renders components would build a new tree that's unable to access the Context data, it would lead to an error message. This would work if only the component Notice is rendered.

I also tried setting variables or flagging when the error occurs in the first place, and then having components detect them to trigger the re-rendering accordingly. However, this PR might be more straightforward.

@pkevan
Copy link
Contributor

pkevan commented May 26, 2023

IMO it's best to show a specific message, because that helps us troubleshoot when someone reports a bug.

Agreed - always easier to have a specific place to start debugging from, rather than needing to reproduce :)

@renintw renintw force-pushed the fix/UI-not-handle-backup-api-fail branch from c174901 to 20249d9 Compare May 30, 2023 00:08
@renintw renintw merged commit 8766c49 into trunk May 30, 2023
@renintw renintw deleted the fix/UI-not-handle-backup-api-fail branch May 30, 2023 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working priority: medium ui Related to user interface
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UI should handle backup endpoint failure
4 participants