Skip to content

Commit 16e09b7

Browse files
committed
Add better error handling
* ensure error appears when an invalid URL is entered * ensure error messages are understandable by users
1 parent 1c1dbc9 commit 16e09b7

File tree

1 file changed

+65
-48
lines changed

1 file changed

+65
-48
lines changed

extensions/ql-vscode/src/databaseFetcher.ts

Lines changed: 65 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -84,29 +84,32 @@ export async function promptImportLgtmDatabase(
8484
});
8585
if (looksLikeLgtmUrl(lgtmUrl)) {
8686
const databaseUrl = await convertToDatabaseUrl(lgtmUrl);
87-
if (!databaseUrl) {
88-
return item;
87+
if (databaseUrl) {
88+
const progressOptions: ProgressOptions = {
89+
location: ProgressLocation.Notification,
90+
title: "Adding database from LGTM",
91+
cancellable: false,
92+
};
93+
await withProgress(
94+
progressOptions,
95+
async (progress) =>
96+
(item = await databaseArchiveFetcher(
97+
databaseUrl,
98+
databasesManager,
99+
storagePath,
100+
progress
101+
))
102+
);
103+
commands.executeCommand("codeQLDatabases.focus");
89104
}
90-
const progressOptions: ProgressOptions = {
91-
location: ProgressLocation.Notification,
92-
title: "Adding database from LGTM",
93-
cancellable: false,
94-
};
95-
await withProgress(
96-
progressOptions,
97-
async (progress) =>
98-
(item = await databaseArchiveFetcher(
99-
databaseUrl,
100-
databasesManager,
101-
storagePath,
102-
progress
103-
))
105+
} else {
106+
throw new Error(`Invalid LGTM URL: ${lgtmUrl}`);
107+
}
108+
if (item) {
109+
showAndLogInformationMessage(
110+
"Database downloaded and imported successfully."
104111
);
105-
commands.executeCommand("codeQLDatabases.focus");
106112
}
107-
showAndLogInformationMessage(
108-
"Database downloaded and imported successfully."
109-
);
110113
} catch (e) {
111114
showAndLogErrorMessage(e.message);
112115
}
@@ -145,9 +148,11 @@ export async function importArchiveDatabase(
145148
);
146149
commands.executeCommand("codeQLDatabases.focus");
147150

148-
showAndLogInformationMessage(
149-
"Database unzipped and imported successfully."
150-
);
151+
if (item) {
152+
showAndLogInformationMessage(
153+
"Database unzipped and imported successfully."
154+
);
155+
}
151156
} catch (e) {
152157
showAndLogErrorMessage(e.message);
153158
}
@@ -323,39 +328,51 @@ function looksLikeLgtmUrl(lgtmUrl: string | undefined): lgtmUrl is string {
323328
return false;
324329
}
325330

326-
const uri = Uri.parse(lgtmUrl, true);
327-
if (uri.scheme !== "https") {
328-
return false;
329-
}
331+
try {
332+
const uri = Uri.parse(lgtmUrl, true);
333+
if (uri.scheme !== "https") {
334+
return false;
335+
}
330336

331-
if (uri.authority !== "lgtm.com" && uri.authority !== "www.lgtm.com") {
337+
if (uri.authority !== "lgtm.com" && uri.authority !== "www.lgtm.com") {
338+
return false;
339+
}
340+
341+
const paths = uri.path.split("/").filter((segment) => segment);
342+
return paths.length === 4 && paths[0] === "projects" && paths[1] === "g";
343+
} catch (e) {
332344
return false;
333345
}
334-
335-
const paths = uri.path.split("/").filter((segment) => segment);
336-
return paths.length === 4 && paths[0] === "projects" && paths[1] === "g";
337346
}
338347

339348
async function convertToDatabaseUrl(lgtmUrl: string) {
340-
const uri = Uri.parse(lgtmUrl, true);
341-
const paths = ["api", "v1.0"].concat(
342-
uri.path.split("/").filter((segment) => segment)
343-
);
344-
const projectUrl = `https://lgtm.com/${paths.join("/")}`;
345-
const projectResponse = await fetch(projectUrl);
346-
const projectJson = await projectResponse.json();
349+
try {
350+
const uri = Uri.parse(lgtmUrl, true);
351+
const paths = ["api", "v1.0"].concat(
352+
uri.path.split("/").filter((segment) => segment)
353+
);
354+
const projectUrl = `https://lgtm.com/${paths.join("/")}`;
355+
const projectResponse = await fetch(projectUrl);
356+
const projectJson = await projectResponse.json();
347357

348-
const language = await promptForLanguage(projectJson);
349-
if (!language) {
350-
return;
358+
if (projectJson.code === 404) {
359+
throw new Error();
360+
}
361+
362+
const language = await promptForLanguage(projectJson);
363+
if (!language) {
364+
return;
365+
}
366+
return `https://lgtm.com/${[
367+
"api",
368+
"v1.0",
369+
"snapshots",
370+
projectJson.id,
371+
language,
372+
].join("/")}`;
373+
} catch (e) {
374+
throw new Error(`Invalid LGTM URL: ${lgtmUrl}`);
351375
}
352-
return `https://lgtm.com/${[
353-
"api",
354-
"v1.0",
355-
"snapshots",
356-
projectJson.id,
357-
language,
358-
].join("/")}`;
359376
}
360377

361378
async function promptForLanguage(

0 commit comments

Comments
 (0)