MED-240: Use retries for medusa query, "ECONNRESET"
This commit is contained in:
@@ -15,6 +15,12 @@ import {
|
||||
removeCartId,
|
||||
setAuthToken,
|
||||
} from './cookies';
|
||||
import { withRetries } from '../util/with-retries';
|
||||
|
||||
const MedusaApiRetriesDefaultConfig = {
|
||||
attempts: 3,
|
||||
baseDelayMs: 1000,
|
||||
};
|
||||
|
||||
export const retrieveCustomer =
|
||||
async (): Promise<HttpTypes.StoreCustomer | null> => {
|
||||
@@ -268,11 +274,21 @@ export const updateCustomerAddress = async (
|
||||
};
|
||||
|
||||
async function medusaLogin(email: string, password: string) {
|
||||
const token = await sdk.auth.login('customer', 'emailpass', {
|
||||
email,
|
||||
password,
|
||||
const token = await withRetries(async () => {
|
||||
const loginToken = await sdk.auth.login('customer', 'emailpass', {
|
||||
email,
|
||||
password,
|
||||
});
|
||||
if (typeof loginToken !== 'string') {
|
||||
throw new Error('Failed to login Medusa account');
|
||||
}
|
||||
return loginToken;
|
||||
}, {
|
||||
...MedusaApiRetriesDefaultConfig,
|
||||
label: 'medusa.auth.login',
|
||||
});
|
||||
await setAuthToken(token as string);
|
||||
|
||||
await setAuthToken(token);
|
||||
|
||||
try {
|
||||
await transferCart();
|
||||
@@ -303,20 +319,38 @@ async function medusaRegister({
|
||||
`Creating new Medusa account for Keycloak user with email=${email}`,
|
||||
);
|
||||
|
||||
const registerToken = await sdk.auth.register('customer', 'emailpass', {
|
||||
email,
|
||||
password,
|
||||
});
|
||||
const registerToken = await withRetries(
|
||||
async () => {
|
||||
const token = await sdk.auth.register('customer', 'emailpass', {
|
||||
email,
|
||||
password,
|
||||
});
|
||||
if (typeof token !== 'string') {
|
||||
throw new Error('Failed to register Medusa account');
|
||||
}
|
||||
return token;
|
||||
},
|
||||
{
|
||||
...MedusaApiRetriesDefaultConfig,
|
||||
label: 'medusa.auth.register',
|
||||
},
|
||||
);
|
||||
await setAuthToken(registerToken);
|
||||
|
||||
console.info(
|
||||
`Creating new Medusa customer profile for Keycloak user with email=${email} and name=${name} and lastName=${lastName}`,
|
||||
);
|
||||
await sdk.store.customer.create(
|
||||
{ email, first_name: name, last_name: lastName },
|
||||
{},
|
||||
await withRetries(
|
||||
async () => {
|
||||
await sdk.store.customer.create(
|
||||
{ email, first_name: name, last_name: lastName },
|
||||
{},
|
||||
{ ...(await getAuthHeaders()) },
|
||||
);
|
||||
},
|
||||
{
|
||||
...(await getAuthHeaders()),
|
||||
...MedusaApiRetriesDefaultConfig,
|
||||
label: 'medusa.customer.create',
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -8,3 +8,4 @@ export * from './money';
|
||||
export * from './product';
|
||||
export * from './repeat';
|
||||
export * from './sort-products';
|
||||
export * from './with-retries';
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
type RetryOptions = {
|
||||
attempts?: number;
|
||||
baseDelayMs?: number;
|
||||
label?: string;
|
||||
};
|
||||
|
||||
function sleep(delay: number) {
|
||||
return new Promise((resolve) => setTimeout(resolve, delay));
|
||||
}
|
||||
|
||||
export async function withRetries<T>(
|
||||
operation: () => Promise<T>,
|
||||
{ attempts = 3, baseDelayMs = 500, label }: RetryOptions = {}
|
||||
): Promise<T> {
|
||||
let lastError: unknown;
|
||||
|
||||
for (let attempt = 1; attempt <= attempts; attempt++) {
|
||||
try {
|
||||
return await operation();
|
||||
} catch (error) {
|
||||
lastError = error;
|
||||
|
||||
if (attempt === attempts) {
|
||||
break;
|
||||
}
|
||||
|
||||
const delay = baseDelayMs * 2 ** (attempt - 1);
|
||||
|
||||
if (label) {
|
||||
console.warn(
|
||||
`Retrying ${label}, attempt ${attempt + 1}/${attempts} in ${delay}ms`,
|
||||
error
|
||||
);
|
||||
}
|
||||
|
||||
if (delay > 0) {
|
||||
await sleep(delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
throw lastError instanceof Error
|
||||
? lastError
|
||||
: new Error("Operation failed after retries");
|
||||
}
|
||||
Reference in New Issue
Block a user