Skip to content

Commit

Permalink
feat(INJI-205): handle timeout error for vc download via issuer
Browse files Browse the repository at this point in the history
the timeout is kept as 30 seconds

Co-authored-by: Harsh Vardhan <[email protected]>
  • Loading branch information
KiruthikaJeyashankar and vharsh committed Oct 9, 2023
1 parent cc9a0f9 commit 4347a96
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 22 deletions.
49 changes: 37 additions & 12 deletions machines/issuersMachine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ import {
VerifiableCredential,
} from '../types/VC/EsignetMosipVC/vc';
import {CACHED_API} from '../shared/api';
import {request} from '../shared/request';

const TIMEOUT_SEC = 10;
const VC_DOWNLOAD_TIMEOUT = 30;

// OIDCErrors is a collection of external errors from the OpenID library or the issuer
enum OIDCErrors {
Expand All @@ -33,6 +34,8 @@ enum OIDCErrors {
OIDC_CONFIG_ERROR_PREFIX = 'Config error',
}

const REQUEST_TIMEDOUT = 'request timedout';

const model = createModel(
{
issuers: [] as issuerType[],
Expand Down Expand Up @@ -110,6 +113,11 @@ export const IssuersMachine = model.createMachine(
actions: 'resetError',
target: 'selectingIssuer',
},
{
cond: 'isRawErrorTimeoutError',
actions: ['resetError'],
target: 'selectingIssuer',
},
{
description: 'not fetched issuers config yet',
actions: ['setLoadingIssuer', 'resetError'],
Expand Down Expand Up @@ -240,10 +248,17 @@ export const IssuersMachine = model.createMachine(
actions: ['setVerifiableCredential', 'setCredentialWrapper'],
target: 'verifyingCredential',
},
onError: {
actions: 'setError',
target: 'error',
},
onError: [
{
cond: 'isVCdownloadTimeout',
actions: ['setOIDCRawError', 'setError'],
target: 'error',
},
{
actions: 'setError',
target: 'error',
},
],
},
on: {
CANCEL: {
Expand Down Expand Up @@ -323,6 +338,12 @@ export const IssuersMachine = model.createMachine(
? event.data.toString()
: '',
}),
setOIDCRawError: model.assign({
rawError: (_, event) => event.data.message,
}),
setRawError: model.assign({
rawError: (_, event) => event.data,
}),
resetError: model.assign({
errorMessage: '',
rawError: '',
Expand Down Expand Up @@ -453,16 +474,16 @@ export const IssuersMachine = model.createMachine(
},
downloadCredential: async context => {
const body = await getBody(context);
const response = await fetch(
const response = await request(
'POST',
context.selectedIssuer.serviceConfiguration.credentialEndpoint,
body,
'',
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: 'Bearer ' + context.tokenResponse?.accessToken,
},
body: JSON.stringify(body),
'Content-Type': 'application/json',
Authorization: 'Bearer ' + context.tokenResponse?.accessToken,
},
VC_DOWNLOAD_TIMEOUT,
);
let credential = await response.json();
credential = updateCredentialInformation(context, credential);
Expand Down Expand Up @@ -510,8 +531,12 @@ export const IssuersMachine = model.createMachine(
event.data.toString().includes(OIDCErrors.OIDC_CONFIG_ERROR_PREFIX)
);
},
isVCdownloadTimeout: (_, event) =>
event.data.message === 'request timedout',
isRawErrorOIDCConfigError: (context, _) =>
context.rawError.includes(OIDCErrors.OIDC_CONFIG_ERROR_PREFIX),
isRawErrorTimeoutError: (context, _) =>
context.rawError.includes(REQUEST_TIMEDOUT),
shouldFetchIssuersAgain: context => context.issuers.length === 0,
isCustomSecureKeystore: () => isCustomSecureKeystore(),
},
Expand Down
3 changes: 3 additions & 0 deletions machines/issuersMachine.typegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ export interface Typegen0 {
setLoadingIssuer: 'TRY_AGAIN';
setNoInternet: 'done.invoke.checkInternet';
setOIDCConfigRawError: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
setOIDCRawError: 'error.platform.issuersMachine.downloadCredentials:invocation[0]';
setPrivateKey: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
setPublicKey: 'done.invoke.issuersMachine.generateKeyPair:invocation[0]';
setSelectedIssuers: 'done.invoke.issuersMachine.downloadIssuerConfig:invocation[0]';
Expand All @@ -117,6 +118,8 @@ export interface Typegen0 {
isOIDCConfigError: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
isOIDCflowCancelled: 'error.platform.issuersMachine.performAuthorization:invocation[0]';
isRawErrorOIDCConfigError: 'TRY_AGAIN';
isRawErrorTimeoutError: 'TRY_AGAIN';
isVCdownloadTimeout: 'error.platform.issuersMachine.downloadCredentials:invocation[0]';
shouldFetchIssuersAgain: 'TRY_AGAIN';
};
eventsCausingServices: {
Expand Down
31 changes: 21 additions & 10 deletions shared/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,42 @@ export async function request(
path: `/${string}`,
body?: Record<string, unknown>,
host = MIMOTO_BASE_URL,
headers: Record<string, string> = {
'Content-Type': 'application/json',
},
timeout?: undefined | number,
) {
const headers = {
'Content-Type': 'application/json',
};
if (path.includes('residentmobileapp'))
headers['X-AppId'] = __AppId.getValue();
let response;
if (timeout === undefined) {
response = await fetch(host + path, {
method,
headers,
body: JSON.stringify(body),
body: body ? JSON.stringify(body) : undefined,
});
} else {
console.log(`making a web request to ${host + path}`);
let controller = new AbortController();
setTimeout(() => {
controller.abort();
}, timeout * 1000);
response = await fetch(host + path, {
method,
headers,
body: JSON.stringify(body),
signal: controller.signal,
});
try {
response = await fetch(host + path, {
method,
headers,
body: body ? JSON.stringify(body) : undefined,
signal: controller.signal,
});
} catch (error) {
console.log(
`Error occurred while making request: ${host + path}: ${error}`,
);
if (error.name === 'AbortError') {
throw new Error('request timedout');
}
throw error;
}
}

const jsonResponse = await response.json();
Expand Down

0 comments on commit 4347a96

Please sign in to comment.