Skip to content

Commit f2575e4

Browse files
committed
Better error handling for downloading dbs at invalid URLs
We do our best to extract a readable error message from the response.
1 parent 87315b8 commit f2575e4

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

extensions/ql-vscode/src/databaseFetcher.ts

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import fetch from "node-fetch";
1+
import fetch, { Response } from "node-fetch";
22
import * as unzipper from "unzipper";
33
import {
44
Uri,
@@ -278,6 +278,9 @@ async function fetchAndUnzip(
278278
progressCallback?: ProgressCallback
279279
) {
280280
const response = await fetch(databaseUrl);
281+
282+
await checkForFailingResponse(response);
283+
281284
const unzipStream = unzipper.Extract({
282285
path: unzipPath,
283286
});
@@ -287,13 +290,37 @@ async function fetchAndUnzip(
287290
step: 2,
288291
});
289292
await new Promise((resolve, reject) => {
290-
response.body.on("error", reject);
291-
unzipStream.on("error", reject);
293+
const handler = (err: Error) => {
294+
if (err.message.startsWith('invalid signature')) {
295+
reject(new Error('Not a valid archive.'));
296+
} else {
297+
reject(err);
298+
}
299+
};
300+
response.body.on("error", handler);
301+
unzipStream.on("error", handler);
292302
unzipStream.on("close", resolve);
293303
response.body.pipe(unzipStream);
294304
});
295305
}
296306

307+
async function checkForFailingResponse(response: Response): Promise<void | never> {
308+
if (response.ok) {
309+
return;
310+
}
311+
312+
// An error downloading the database. Attempt to extract the resaon behind it.
313+
const text = await response.text();
314+
let msg: string;
315+
try {
316+
const obj = JSON.parse(text);
317+
msg = obj.error || obj.message || obj.reason || JSON.stringify(obj, null, 2);
318+
} catch (e) {
319+
msg = text;
320+
}
321+
throw new Error(`Error downloading database.\n\nReason: ${msg}`);
322+
}
323+
297324
function isFile(databaseUrl: string) {
298325
return Uri.parse(databaseUrl).scheme === "file";
299326
}
@@ -409,7 +436,7 @@ async function promptForLanguage(
409436

410437
return await window.showQuickPick(
411438
projectJson.languages.map((lang: { language: string }) => lang.language), {
412-
placeHolder: "Select the database language to download:"
413-
}
439+
placeHolder: "Select the database language to download:"
440+
}
414441
);
415442
}

0 commit comments

Comments
 (0)