Skip to content

Commit 7ab3c88

Browse files
committed
feat: automatically retry if vscode download fails
1 parent cabeacc commit 7ab3c88

File tree

3 files changed

+36
-16
lines changed

3 files changed

+36
-16
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
### 2.1.4 | 2022-06-27
4+
5+
- Automatically retry if VS Code download fails
6+
37
### 2.1.4 | 2022-06-10
48

59
- Fix uncaught error when failing to connect to the extension service

lib/download.ts

+17-7
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ const extensionRoot = process.cwd();
2121

2222
const vscodeStableReleasesAPI = `https://update.code.visualstudio.com/api/releases/stable`;
2323

24+
const DOWNLOAD_ATTEMPTS = 3;
25+
2426
async function fetchLatestStableVersion(): Promise<string> {
2527
const versions = await request.getJSON(vscodeStableReleasesAPI);
2628
if (!versions || !Array.isArray(versions) || !versions[0]) {
@@ -228,14 +230,22 @@ export async function download(options: Partial<DownloadOptions> = {}): Promise<
228230
}
229231
}
230232

231-
try {
232-
const { stream, format } = await downloadVSCodeArchive({ version, platform, cachePath, reporter });
233-
await unzipVSCode(reporter, downloadedPath, extractSync, stream, format);
234-
reporter.report({ stage: ProgressReportStage.NewInstallComplete, downloadedPath })
235-
} catch (err) {
236-
reporter.error(err);
237-
throw Error(`Failed to download and unzip VS Code ${version}`);
233+
for (let i = 0;; i++) {
234+
try {
235+
const { stream, format } = await downloadVSCodeArchive({ version, platform, cachePath, reporter });
236+
await unzipVSCode(reporter, downloadedPath, extractSync, stream, format);
237+
reporter.report({ stage: ProgressReportStage.NewInstallComplete, downloadedPath })
238+
break;
239+
} catch (error) {
240+
if (i++ < DOWNLOAD_ATTEMPTS) {
241+
reporter.report({ stage: ProgressReportStage.Retrying, attempt: i, error: error as Error, totalAttempts: DOWNLOAD_ATTEMPTS });
242+
} else {
243+
reporter.error(error);
244+
throw Error(`Failed to download and unzip VS Code ${version}`);
245+
}
246+
}
238247
}
248+
reporter.report({ stage: ProgressReportStage.NewInstallComplete, downloadedPath })
239249

240250
if (version === 'insiders') {
241251
return Promise.resolve(insidersDownloadDirToExecutablePath(downloadedPath, platform));

lib/progress.ts

+15-9
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ export enum ProgressReportStage {
2121
Downloading = 'downloading',
2222
/** Fired when the command is issued to do a synchronous extraction. May not fire depending on the platform and options. */
2323
ExtractingSynchonrously = 'extractingSynchonrously',
24+
/** Fired when the download fails and a retry will be attempted */
25+
Retrying = 'retrying',
2426
/** Fired after folder is downloaded and unzipped */
2527
NewInstallComplete = 'newInstallComplete',
2628
}
@@ -33,6 +35,7 @@ export type ProgressReport =
3335
| { stage: ProgressReportStage.FoundMatchingInstall; downloadedPath: string }
3436
| { stage: ProgressReportStage.ResolvingCDNLocation; url: string }
3537
| { stage: ProgressReportStage.Downloading; url: string; totalBytes: number; bytesSoFar: number; }
38+
| { stage: ProgressReportStage.Retrying; error: Error, attempt: number; totalAttempts: number }
3639
| { stage: ProgressReportStage.ExtractingSynchonrously; }
3740
| { stage: ProgressReportStage.NewInstallComplete, downloadedPath: string; }
3841

@@ -76,9 +79,6 @@ export class ConsoleReporter implements ProgressReporter {
7679
case ProgressReportStage.FoundMatchingInstall:
7780
console.log(`Found existing install in ${report.downloadedPath}. Skipping download`);
7881
break;
79-
case ProgressReportStage.NewInstallComplete:
80-
console.log(`Downloaded VS Code ${this.version} into ${report.downloadedPath}`);
81-
break;
8282
case ProgressReportStage.ResolvingCDNLocation:
8383
console.log(`Downloading VS Code ${this.version} from ${report.url}`)
8484
break;
@@ -91,13 +91,12 @@ export class ConsoleReporter implements ProgressReporter {
9191
this.downloadReport.report = report;
9292
}
9393
break;
94+
case ProgressReportStage.Retrying:
95+
this.flushDownloadReport();
96+
console.log(`Error downloading, retrying (attempt ${report.attempt} of ${report.totalAttempts}): ${report.error.message}`);
97+
break;
9498
case ProgressReportStage.NewInstallComplete:
95-
if (this.downloadReport) {
96-
clearTimeout(this.downloadReport.timeout);
97-
}
98-
if (this.showDownloadProgress) {
99-
console.log('');
100-
}
99+
this.flushDownloadReport();
101100
console.log(`Downloaded VS Code into ${report.downloadedPath}`);
102101
break;
103102
}
@@ -107,6 +106,13 @@ export class ConsoleReporter implements ProgressReporter {
107106
console.error(err);
108107
}
109108

109+
private flushDownloadReport() {
110+
if (this.showDownloadProgress) {
111+
this.reportDownload();
112+
console.log('');
113+
}
114+
}
115+
110116
private reportDownload() {
111117
if (!this.downloadReport) {
112118
return;

0 commit comments

Comments
 (0)