diff --git a/editors/code/package-lock.json b/editors/code/package-lock.json index 5c056463e0..e737d6aceb 100644 --- a/editors/code/package-lock.json +++ b/editors/code/package-lock.json @@ -753,6 +753,11 @@ "os-tmpdir": "~1.0.1" } }, + "ts-nested-error": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/ts-nested-error/-/ts-nested-error-1.1.3.tgz", + "integrity": "sha512-CJSRAhXr6phdkuu65U/ctkY/TBzjkg2g1sL9juSG/PP3ONQNCbeksMy54OfCBTUt13hSpHNbnTO1OBPunOHj/Q==" + }, "tslib": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", diff --git a/editors/code/package.json b/editors/code/package.json index f687eb8d45..ce7117c694 100644 --- a/editors/code/package.json +++ b/editors/code/package.json @@ -27,6 +27,7 @@ "jsonc-parser": "^2.1.0", "node-fetch": "^2.6.0", "throttle-debounce": "^2.1.0", + "ts-nested-error": "^1.1.3", "vscode-languageclient": "^6.1.0" }, "devDependencies": { diff --git a/editors/code/src/installation/download_file.ts b/editors/code/src/installation/download_file.ts index f1f9f4a256..71700ec8ae 100644 --- a/editors/code/src/installation/download_file.ts +++ b/editors/code/src/installation/download_file.ts @@ -1,6 +1,9 @@ import fetch from "node-fetch"; import * as fs from "fs"; import { strict as assert } from "assert"; +import { NestedError } from "ts-nested-error"; + +class DownloadFileError extends NestedError {} /** * Downloads file from `url` and stores it at `destFilePath` with `destFilePermissions`. @@ -14,13 +17,13 @@ export async function downloadFile( destFilePermissions: number, onProgress: (readBytes: number, totalBytes: number) => void ): Promise { - const res = await fetch(url); + const res = await fetch(url).catch(DownloadFileError.rethrow("Failed at initial fetch")); if (!res.ok) { console.log("Error", res.status, "while downloading file from", url); console.dir({ body: await res.text(), headers: res.headers }, { depth: 3 }); - throw new Error(`Got response ${res.status} when trying to download a file`); + throw new DownloadFileError(`Got response ${res.status}`); } const totalBytes = Number(res.headers.get('content-length')); @@ -30,15 +33,21 @@ export async function downloadFile( console.log("Downloading file of", totalBytes, "bytes size from", url, "to", destFilePath); + // Here reject() may be called 2 times. As per ECMAScript standard, 2-d call is ignored + // https://tc39.es/ecma262/#sec-promise-reject-functions + return new Promise((resolve, reject) => res.body .on("data", (chunk: Buffer) => { readBytes += chunk.length; onProgress(readBytes, totalBytes); }) - .on("error", reject) - .pipe(fs - .createWriteStream(destFilePath, { mode: destFilePermissions }) - .on("close", resolve) - ) + .on("error", err => reject( + new DownloadFileError(`Read-stream error, read bytes: ${readBytes}`, err) + )) + .pipe(fs.createWriteStream(destFilePath, { mode: destFilePermissions })) + .on("error", err => reject( + new DownloadFileError(`Write-stream error, read bytes: ${readBytes}`, err) + )) + .on("close", resolve) ); } diff --git a/editors/code/src/installation/language_server.ts b/editors/code/src/installation/language_server.ts index 52c5cbe7d6..4797c3f01a 100644 --- a/editors/code/src/installation/language_server.ts +++ b/editors/code/src/installation/language_server.ts @@ -104,6 +104,8 @@ export async function ensureLanguageServerBinary( `GitHub repository: ${err.message}` ); + console.error(err); + dns.resolve('example.com').then( addrs => console.log("DNS resolution for example.com was successful", addrs), err => {