-
Notifications
You must be signed in to change notification settings - Fork 130
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
@W-15490276@ Better refresh token error logging for V3 #2028
Conversation
await this.logTokenRequestError(error as Error) | ||
throw error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because error.response
has been consumed with json()
, when we throw an error here, the caller can no longer read what's inside error.response
anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh, inspired by what's seen in your other PR: rather than reusing the same error, let's create a new error (with HTTPError
) and throw that one instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've updated this to throw a new Error (since commerce-sdk-react currently does not have access to HTTPError).
const json = await (error['response'] as Response).json() | ||
const status_code: string = json.status_code | ||
const responseMessage: string = json.message | ||
|
||
this.logger.error(`${status_code} ${responseMessage}`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similar to the previous comment, do we really need to log the response details?
I think as long as we handle any refresh token errors (rather than one with a specific error message), then this is already better error handling than before.
Another way to put it is that in the case of refresh token errors, IMO gracefully handling those errors (by clearing storage and then restarting the login flow) is more important than the logging part.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we do need to log the response details because there are a variety of different types of problems that SLAS could respond with and we don't want this to happen in a place where developers can't get into our SDK to get those clarifying response error messages that are missing
In "development mode" they can look at the Network tab in Chrome, but if a customer hits an error and can't reproduce it / the dev tools weren't already open, seeing the verbose message would become critical in catching and fixing errors in production
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI done reviewing.
expect(refreshAccessTokenSpy).toHaveBeenCalled() | ||
expect(helpers.loginGuestUser).toHaveBeenCalled() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we also want to check whether the storage or refresh token has been updated properly afterwards?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've added a check to verify that the storage has been cleared after the refresh attempt.
Testing that the loginGuestUser has updated the refresh token isn't too valuable since it's a mock method that we'd define and control in the test. Testing that the token has been replaced is better done in an e2e test that involves actual SLAS calls.
I think for our unit tests, it is enough to verify that loginGuestUser has been invoked.
try { | ||
return await this.queueRequest(callback, isGuest) | ||
} catch (error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for catching and handling this additional scenario 👍
// ie. 'Bad Request' for 400. We need to drill specifically into the ResponseError | ||
// to get a more descriptive error message from SLAS | ||
if (error instanceof Error && 'response' in error) { | ||
// commerce-sdk-isomorphic throws a `ResponseError`, but doesn't export the class. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We control this package so there's nothing stopping from exporting it :D
but the release wouldn't make it in time for this PR, so maybe we can export it in the next release and follow up in another PR if we really want to
// We catch the error here to do logging but we still need to | ||
// throw an error to stop the login flow from continuing. | ||
await this.logTokenRequestError(err) | ||
throw new Error(`New guest user could not be logged in. ${err.message}`) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This way the caller would also not have access to read the response details. How can we pass along those details to them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've made changes for extracting the status code and message from the ResponseError so that they can be passed around.
// clean up storage and restart the login flow | ||
this.clearStorage() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Minor: how about us console.log
ing here to tell others that we've handled the error by doing a guest login? I think it'd be useful for them to see that in the log too... not just the errors.
@@ -1,5 +1,6 @@ | |||
## v3.1.0-dev (Aug 08, 2024) | |||
|
|||
- Better refresh token error logging [#2028](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2028) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Better refresh token error logging [#2028](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2028) | |
- Improve refresh token error logging [#2028](https://github.com/SalesforceCommerceCloud/pwa-kit/pull/2028) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Applied!
Related to #1829
There are a few ways in which a call to SLAS to consume a refresh token can fail. For example, the client id the refresh token is associated with might be different from the client id included with the request.
Before this change, the error logging for a failed refresh token call only triggered when SLAS returned the error message 'invalid refresh token'.
This change opens up the logging so that any failed refresh token call error message is logged.
This change also updates new guest login to also log error messages.
Testing the changes:
Refresh login (note: the refresh login request happens client side only):
commerce-sdk-react ERROR invalid organizationId
New guest login: