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

Better error type identification in the browser #357

Closed
mhamann opened this issue Feb 14, 2023 · 10 comments · Fixed by #367
Closed

Better error type identification in the browser #357

mhamann opened this issue Feb 14, 2023 · 10 comments · Fixed by #367

Comments

@mhamann
Copy link

mhamann commented Feb 14, 2023

Describe the issue

When catching errors thrown by the browser API, it's desirable to identify what type of error occurred so that the user experience can be altered accordingly.

For example, did the user cancel the authentication? Was the browser unable to fulfill the request for some reason? Based on the error thrown, the user could be prompted to try again, or in some cases (e.g., browser autofill init), just ignore the error altogether.

This would also help cases where autofill and explicit startAuthentication() requests are used in parallel: one to help a user leverage an existing passkey even if they're not familiar with the terminology and another for users who know what they want immediately. The autofill request might be intentionally cancelled due to a more explicit request being initiated.

Currently, the library throws generic Errors, but it would be useful to customize those errors and set some sort of code property that can be programmatically relied upon to not change, even though english string messaging might. (e.g., code: E_CANCELLED or code: E_NO_INPUTS)

I am happy to PR changes in this regard if its agreed that this would be a helpful addition.

SimpleWebAuthn Libraries

$ npm list --depth=0 | grep @simplewebauthn
├── @simplewebauthn/browser@7.0.1
├── @simplewebauthn/typescript-types@7.0.0
@MasterKale
Copy link
Owner

MasterKale commented Feb 14, 2023

Hmm, it's true that Errors are being returned, but it's their name properties that differentiate the errors. @simplewebauthn/browser keeps the error name for spec compliance, but overwrites the message when it feels confident it knows why the more general error was thrown.

This proposal could be interpreted as a request to introduce SimpleWebAuthn-specific error codes. Is that the direction you're thinking this would go?

@mhamann
Copy link
Author

mhamann commented Feb 15, 2023

Thanks for the follow up. Yes, exactly--I was thinking these would be lib-specific error codes. Right now, I'm parsing the message in order to do some differentiation, but that will likely be brittle long-term.

@MasterKale
Copy link
Owner

I was poking around Error on MDN and learned about cause:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause

Perhaps I can use this here 🤔

@mhamann
Copy link
Author

mhamann commented Feb 16, 2023

That seems workable. I also tested Opera (listed as not supporting Error.cause), and it seemed to work fine. I opened an issue with MDN to hopefully update or clarify the documentation.

@MasterKale
Copy link
Owner

So far what I'm thinking of doing is creating a custom error (when I don't pass through the WebAuthn error), and including the original error as cause. I need your opinion though. Do I:

  1. Throw a single "SimpleWebAuthnError" from both startRegistration() and startAuthentication(), differentiating registration or authentication errors by error code (e.g. "ERR_REG_FOO", "ERR_AUTH_BAR", etc...)
  2. Throw a single "SimpleWebAuthnError" from both startRegistration() and startAuthentication(), and error codes are more general (e.g. "ERR_FOO", "ERR_BAR", etc...) because the type is implied by the error handler wrapping either method
  3. Throw a "RegistrationError" from startRegistration(), and an "AuthenticationError" from startAuthentication(), and error codes are more general (e.g. "ERR_FOO", "ERR_BAR", etc...)

I'm between 1 and 2 right now, maybe preferring 2 because if any error messages are similar between the two then I can reuse error codes.

@mhamann
Copy link
Author

mhamann commented Feb 17, 2023

I like 2 as well. The context is implied, which makes handling errors from either function similar.

@MasterKale
Copy link
Owner

@mhamann I'm working on #367 to finally address this. What do you think about the following error codes?

  • 'ERROR_CEREMONY_ABORTED'
  • 'ERROR_INVALID_DOMAIN'
  • 'ERROR_INVALID_RP_ID'
  • 'ERROR_INVALID_USER_ID_LENGTH'
  • 'ERROR_MALFORMED_PUBKEYCREDPARAMS'
  • 'ERROR_AUTHENTICATOR_GENERAL_ERROR'
  • 'ERROR_AUTHENTICATOR_MISSING_DISCOVERABLE_CREDENTIAL_SUPPORT'
  • 'ERROR_AUTHENTICATOR_MISSING_USER_VERIFICATION_SUPPORT'
  • 'ERROR_AUTHENTICATOR_PREVIOUSLY_REGISTERED'
  • 'ERROR_AUTHENTICATOR_NO_SUPPORTED_PUBKEYCREDPARAMS_ALG'
  • 'ERROR_PASSTHROUGH_SEE_CAUSE_PROPERTY'

Now's the time to make suggestions if any of these seem off for whatever reason.

@mhamann
Copy link
Author

mhamann commented Mar 3, 2023

This looks fantastic. I can't think of anything missing, and those seem nicely descriptive of what caused the error.

@MasterKale
Copy link
Owner

@mhamann I just published @simplewebauthn/browser@7.2.0 that should resolve this issue 🚀

@mhamann
Copy link
Author

mhamann commented Mar 16, 2023

Thanks very much! We'll upgrade ASAP!

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 a pull request may close this issue.

2 participants