PluginProbe
Extendify / 3.1.5
Extendify v3.1.5
3.2.1 3.2.0 3.1.6 3.1.5 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.6 3.0.5 3.0.4 trunk 0.1.0 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.2.0 0.3.0 0.3.1 0.4.0 0.5.0 0.6.0 All 127 releases
extendify / src / Shared / components / ProductAccountActivation / createAccount.js

createAccount.js in Extendify 3.1.5, at src/Shared/components/ProductAccountActivation/createAccount.js

90 lines 2.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 const describeError = (error, signal) => ({
2 message: error?.message,
3 code: error?.code,
4 data: error?.data,
5 // api-fetch collapses our AbortSignal.timeout into a generic fetch_error.
6 timedOut: signal.aborted,
7 });
8
9 export async function createAccount(plugin, data) {
10 if (!plugin?.idempotent) {
11 const signal = AbortSignal.timeout(15000);
12 const timings = {};
13 const attemptStart = Date.now();
14
15 try {
16 await plugin.createAccountCallback({ ...data, signal, timings });
17
18 return {
19 requestTimeInMs: [Date.now() - attemptStart],
20 captchaTimeInMs: timings.captchaTimeInMs,
21 retries: 0,
22 errors: [],
23 };
24 } catch (error) {
25 const err = new Error('Single attempt failed');
26
27 err.requestTimeInMs = [Date.now() - attemptStart];
28 err.captchaTimeInMs = timings.captchaTimeInMs;
29 err.retries = 0;
30 err.errors = [describeError(error, signal)];
31
32 throw err;
33 }
34 }
35
36 return createAccountWithRetry(plugin, data);
37 }
38
39 async function createAccountWithRetry(
40 plugin,
41 { email, marketingConsent, termsAgreed, scriptData },
42 ) {
43 const windowMs = 10000;
44 const perAttemptMs = 5000;
45 const backoffMs = 2500;
46 const maxRetries = 5;
47
48 const windowStart = Date.now();
49 const requestTimeInMs = [];
50 const errors = [];
51 let retries = 0;
52
53 while (Date.now() - windowStart < windowMs && retries < maxRetries) {
54 const attemptStart = Date.now();
55 const signal = AbortSignal.timeout(perAttemptMs);
56
57 try {
58 await plugin.createAccountCallback({
59 email,
60 marketingConsent,
61 termsAgreed,
62 scriptData,
63 signal,
64 });
65 requestTimeInMs.push(Date.now() - attemptStart);
66 return { requestTimeInMs, retries, errors };
67 } catch (error) {
68 requestTimeInMs.push(Date.now() - attemptStart);
69
70 errors.push(describeError(error, signal));
71
72 const remainingMs = windowMs - (Date.now() - windowStart);
73
74 if (remainingMs <= 0) break;
75
76 retries++;
77
78 if (!signal.aborted && remainingMs >= backoffMs) {
79 await new Promise((resolve) => setTimeout(resolve, backoffMs));
80 }
81 }
82 }
83
84 const err = new Error(`Retry window of ${windowMs}ms exceeded`);
85 err.requestTimeInMs = requestTimeInMs;
86 err.retries = retries;
87 err.errors = errors;
88 throw err;
89 }
90