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

feat(INJI-205): Error handling in OIDC flow #878

Merged
merged 20 commits into from
Oct 10, 2023

Conversation

vharsh
Copy link
Member

@vharsh vharsh commented Sep 29, 2023

User visible scenarios handled

  1. [DONE] On loss of internet connectivity --> No internet connectivity message shown
  2. [DONE] Invalid broken URL --> the library will pass a config error hence this will result in a generic error
  3. [DONE] Request timeout --> Something went wrong message shown
  4. [DONE] User cancels OpenID4VC flow --> back button is pressed, no error shown as it's not an error and the error is handled for both Android & iOS platforms.

Code changes

  • issuerMachine: add intermediary states for managing errors and internet connectivity checks
  • add an optional param in shared/request.ts for requestTimeout without breaking other's changes

What needs to be improved ?

  • efficacy of timeout handling on fetch is sort of debatable, it'd need to be tested well this has been implemented using AbortController's polyfill added in ReactNative 0.60, hence it works on React Native 0.60 & above

Request timeout feature implementation

  • AbortController was added from RN 0.60 using an AbortController polyfill(this worked on iPhone 7 & Nokia 6.1+) using this sample code
...
const banana = request('GET', '/', undefined, 2, 'http://[REDACTED]')
          .then((x) => console.log('Success:', x))
          .catch((e) => console.log('Banana Failure', e));
...

The server writing the response for the above request had a sleep for 10seconds, the server did wait for 10seconds to write the response but from the client logs the Promise got rejected with this log. The logs are sort of a real-world proof that the timeout should work on physical devices.

// iPhone 7 test
 LOG  [Harsh Vardhan’s iPhone] app: ONLINE -> ready.focus.checking
{
  "networkType": "wifi"
}
 LOG  Banana Failure [AbortError: Aborted]

// Android 10, Nokia 6.1+ test

 LOG  [46a5f0c3] app: ONLINE -> ready.focus.checking
{
  "networkType": "wifi"
}
 LOG  Banana Failure [AbortError: Aborted]

@vharsh vharsh marked this pull request as ready for review October 4, 2023 05:40
@@ -16,30 +16,41 @@ export async function request(
method: 'GET' | 'POST' | 'PATCH',
path: `/${string}`,
body?: Record<string, unknown>,
timeout?: undefined | number,
Copy link
Contributor

Choose a reason for hiding this comment

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

Let's add timeout as last parameter as it's optional.

Copy link
Contributor

Choose a reason for hiding this comment

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

After this change, I am hoping QR login will not work as we are sending ESIGNET_HOST as last argument in function call. Please check it once.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm a bit confused with the definitive/recommended order of parameters in typescript and I've not found the guidelines on the order of parameters of different types such as normal, optional and default.

@vharsh vharsh force-pushed the feature-205-error-vc-download branch 5 times, most recently from 962512b to 9f8c778 Compare October 9, 2023 06:28
@KiruthikaJeyashankar KiruthikaJeyashankar force-pushed the feature-205-error-vc-download branch from 07eea13 to 4347a96 Compare October 9, 2023 12:57
{
description: 'not fetched issuers config yet',
cond: 'shouldFetchIssuersAgain',
actions: ['setLoadingIssuer', 'resetError'],
Copy link
Contributor

Choose a reason for hiding this comment

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

since we are updating the loadingReason context, can we rename setLoadingIssuer to setLoadingReason.

Copy link
Contributor

Choose a reason for hiding this comment

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

we are updating loading reason to be 'loading issuers' and in other areas we update loading reason to downloading credentials & so. so we are using setLoadingIssuers name for the action to differentiate loadingReason setup for different areas.

Copy link
Contributor

Choose a reason for hiding this comment

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

Renamed function accordingly

setDownloadingCreds: model.assign({
loadingReason: 'downloadingCredentials',
}),
setTokenLoadingReason: model.assign({
Copy link
Contributor

Choose a reason for hiding this comment

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

instead of separate setter for Loading Reason context variable, can't we pass a argument and unify them
image

Copy link
Contributor

@KiruthikaJeyashankar KiruthikaJeyashankar Oct 10, 2023

Choose a reason for hiding this comment

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

You mean like inline actions? if so, Wouldn't inline actions make it hard to debug / visualize the machine?

Copy link
Contributor

Choose a reason for hiding this comment

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

Renamed function accordingly

vharsh and others added 12 commits October 10, 2023 13:34
- `internet not available` on network request failure to issuer
- generic error message on other errors in the flow
- OIDC flow cancel error message

Signed-off-by: Kiruthika Jeyashankar <[email protected]>
granular level changes:
    - merged error states
    - move to a two-step issuer-ID assign of issuer from issuerScreen to
      state machine
    - improved OIDC cancel flow handling for android/iOS openid platform libs

Co-authored-by: Kiruthika Jeyashankar <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Co-authored-by: Kiruthika Jeyashankar <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Co-authored-by: Kiruthika Jeyashankar <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Co-authored-by: Kiruthika Jeyashankar <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
the timeout is kept as 30 seconds

Co-authored-by: Harsh Vardhan <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Co-authored-by: Harsh Vardhan <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Co-authored-by: Kiruthika Jeyashankar <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Co-authored-by: Kiruthika Jeyashankar <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
@KiruthikaJeyashankar KiruthikaJeyashankar force-pushed the feature-205-error-vc-download branch from afc30a5 to bcd500f Compare October 10, 2023 08:08
@@ -92,3 +92,20 @@ export const getJWT = async context => {
throw e;
}
};
export const VC_DOWNLOAD_TIMEOUT = 30;
Copy link
Contributor

Choose a reason for hiding this comment

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

can we move this property to inji-default.properties

Copy link
Contributor

Choose a reason for hiding this comment

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

yes, let's move it to inji-default.properties and add as Initial config which is being used for caching

Copy link
Contributor

Choose a reason for hiding this comment

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

Change included

REQUEST_TIMEDOUT = 'requestTimedOut',
}
export const NETWORK_REQUEST_FAILED = 'Network request failed';
export const REQUEST_TIMEOUT = 'request timedout';
Copy link
Contributor

Choose a reason for hiding this comment

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

request.ts is not using this constant REQUEST_TIMEOUT variable

Copy link
Contributor

Choose a reason for hiding this comment

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

Refactored

KiruthikaJeyashankar and others added 5 commits October 10, 2023 16:19
Co-authored-by: Harsh Vardhan <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Co-authored-by: Harsh Vardhan <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Co-authored-by: Harsh Vardhan <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Co-authored-by: Harsh Vardhan <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Co-authored-by: Harsh Vardhan <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
actions: ['setPublicKey', 'setPrivateKey', 'storeKeyPair'],
actions: [
'setPublicKey',
'setLoadingReasonAsDownloadingCreds',
Copy link
Contributor

Choose a reason for hiding this comment

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

please remove the abbreviation "creds" and use full name for more clarity "credential"

Copy link
Contributor

Choose a reason for hiding this comment

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

Refactored

return state.context.errorMessage;
export function selectErrorMessageType(state: State) {
return state.context.errorMessage === '' ||
state.context.errorMessage === 'noInternetConnection'
Copy link
Contributor

Choose a reason for hiding this comment

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

please use the ErrorMessage enums here as well

Copy link
Contributor

Choose a reason for hiding this comment

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

Refactored

@@ -50,14 +54,18 @@ export const IssuersScreen: React.FC<
};

const isGenericError = () => {
return controller.errorMessage === 'generic';
return controller.errorMessageType === 'generic';
Copy link
Contributor

Choose a reason for hiding this comment

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

use ErrorMessage enum here as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

Refactored

@@ -92,3 +93,19 @@ export const getJWT = async context => {
throw e;
}
};
export const VC_DOWNLOAD_TIMEOUT =
Number(getConfig('openId4VCIDownloadVCTimeout')) || 30000;
Copy link
Contributor

Choose a reason for hiding this comment

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

dont need default value 30000 here, as cached response itself will set it, if not avl.

Copy link
Member Author

Choose a reason for hiding this comment

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

If the promise fails to resolve or the key is missing from the server, the promise.catch would return '' and Number('') would evaluate to 0, hence this or condition is required.

@@ -10,6 +10,14 @@ export default async function getAllConfigurations(host = undefined) {
return await CACHED_API.getAllProperties();
}

export function getConfig(key: string): string {
Copy link
Contributor

Choose a reason for hiding this comment

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

please remove this function and use getAllConfiguration, no need for separate function.

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a helper function we've written for future convenience usage

Copy link
Contributor

Choose a reason for hiding this comment

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

Refactored to use getAllConfigurations

KiruthikaJeyashankar and others added 2 commits October 10, 2023 18:59
Co-authored-by: Harsh Vardhan <[email protected]>
Signed-off-by: Kiruthika Jeyashankar <[email protected]>
Copy link
Contributor

@vijay151096 vijay151096 left a comment

Choose a reason for hiding this comment

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

changes looks good to me.

@vijay151096 vijay151096 merged commit e5963cf into mosip:develop Oct 10, 2023
1 of 3 checks passed
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.

4 participants