Skip to content

Commit 6f24908

Browse files
authored
[Google import] Add resilience to download data (#2001)
* fix: add retry to userId parsing and a longer sleep before download * fix: wait infinitely for download link * fix: remove sleep and move retry limits to settings * refactor: poll forever as android will time out anyway * fix: check the link before parsing * fix: sleep before download * refactor: move sleep to config
1 parent 1f66b13 commit 6f24908

File tree

1 file changed

+32
-11
lines changed

1 file changed

+32
-11
lines changed

injected/src/features/autofill-import.js

Lines changed: 32 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -590,23 +590,44 @@ export default class AutofillImport extends ActionExecutorBase {
590590

591591
/** Bookmark import code */
592592
async downloadData() {
593-
// sleep for a second, sometimes download link is not yet available
594-
await new Promise((resolve) => setTimeout(resolve, 1000));
595-
596-
const userId = document.querySelector(this.bookmarkImportSelectorSettings.userIdLink)?.getAttribute('href')?.split('&user=')[1];
597-
await this.runWithRetry(() => document.querySelector(`a[href="./manage/archive/${this.#exportId}"]`), 15, 2000, 'linear');
598-
if (userId != null && this.#exportId != null) {
599-
const downloadURL = `${TAKEOUT_DOWNLOAD_URL_BASE}?j=${this.#exportId}&i=0&user=${userId}`;
600-
window.location.href = downloadURL;
601-
} else {
602-
// If there's no user id or export id, we post an action failed message
593+
// Run with retry forever until the download link is available,
594+
// Android is the one that timesout anyway and closes the whole tab if this doesn't complete
595+
const downloadRetryLimit = this.getFeatureSetting('downloadRetryLimit') ?? Infinity;
596+
const downloadRetryInterval = this.getFeatureSetting('downloadRetryInterval') ?? 1000;
597+
598+
const userIdElement = await this.runWithRetry(
599+
() => document.querySelector(this.bookmarkImportSelectorSettings.userIdLink),
600+
downloadRetryLimit,
601+
downloadRetryInterval,
602+
'linear',
603+
);
604+
const userIdLink = userIdElement?.getAttribute('href');
605+
const userId = userIdLink ? new URL(userIdLink, window.location.origin).searchParams.get('user') : null;
606+
607+
if (!userId || !this.#exportId) {
603608
this.postBookmarkImportMessage('actionCompleted', {
604609
result: new ErrorResponse({
605610
actionID: 'download-data',
606-
message: 'No user id or export id found',
611+
message: 'User id or export id not found',
607612
}),
608613
});
614+
return;
609615
}
616+
617+
await this.runWithRetry(
618+
() => document.querySelector(`a[href="./manage/archive/${this.#exportId}"]`),
619+
downloadRetryLimit,
620+
downloadRetryInterval,
621+
'linear',
622+
);
623+
624+
const downloadURL = `${TAKEOUT_DOWNLOAD_URL_BASE}?j=${this.#exportId}&i=0&user=${userId}`;
625+
626+
// Sleep before downloading to ensure the download link is available
627+
const downloadNavigationDelayMs = this.getFeatureSetting('downloadNavigationDelayMs') ?? 2000;
628+
await new Promise((resolve) => setTimeout(resolve, downloadNavigationDelayMs));
629+
630+
window.location.href = downloadURL;
610631
}
611632

612633
/**

0 commit comments

Comments
 (0)