Fix sticky Square SDK rejection and clean up script element on failure
A load that resolved the script tag but failed to expose window.Square (or timed out) permanently cached a rejected promise, bricking card entry until reload. sdkPromise now resets and the injected script element is removed on every failure path so later calls retry fresh.
This commit is contained in:
@@ -70,16 +70,28 @@ export function loadSquareSdk(): Promise<unknown> {
|
|||||||
script.src = sdkUrl();
|
script.src = sdkUrl();
|
||||||
script.async = true;
|
script.async = true;
|
||||||
script.dataset.squareSdk = 'true';
|
script.dataset.squareSdk = 'true';
|
||||||
|
|
||||||
|
// Non-sticky-rejection invariant: a FAILED load attempt must never poison
|
||||||
|
// the cached promise. Concurrent callers during one attempt share the same
|
||||||
|
// in-flight promise (good — single script load), but a REJECTED promise is
|
||||||
|
// cleared here so the next getSquarePayments() call starts a fresh attempt
|
||||||
|
// instead of returning the same error forever. The dead <script> is also
|
||||||
|
// detached so a retry injects a clean element.
|
||||||
|
const fail = (error: Error) => {
|
||||||
|
script.remove();
|
||||||
|
sdkPromise = null;
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
|
||||||
script.onload = () => {
|
script.onload = () => {
|
||||||
if (win.Square) {
|
if (win.Square) {
|
||||||
resolve(win.Square);
|
resolve(win.Square);
|
||||||
} else {
|
} else {
|
||||||
reject(new Error('Square.js loaded but the Square global is missing'));
|
fail(new Error('Square.js loaded but the Square global is missing'));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
script.onerror = () => {
|
script.onerror = () => {
|
||||||
sdkPromise = null;
|
fail(new Error('Failed to load Square Web Payments SDK'));
|
||||||
reject(new Error('Failed to load Square Web Payments SDK'));
|
|
||||||
};
|
};
|
||||||
document.head.appendChild(script);
|
document.head.appendChild(script);
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user