Skip to content

Commit

Permalink
Added rate-limit warning
Browse files Browse the repository at this point in the history
Signed-off-by: paulober <[email protected]>
  • Loading branch information
paulober committed Sep 6, 2024
1 parent 48f777d commit ca4bce8
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 4 deletions.
21 changes: 21 additions & 0 deletions src/utils/download.mts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
GITHUB_API_VERSION,
HTTP_STATUS_UNAUTHORIZED,
githubApiUnauthorized,
HTTP_STATUS_FORBIDDEN,
} from "./githubREST.mjs";
import { unxzFile, unzipFile } from "./downloadHelpers.mjs";
import type { Writable } from "stream";
Expand Down Expand Up @@ -540,6 +541,8 @@ async function downloadAndInstallGithubAsset(
maxRedirections: 0, // don't automatically follow redirects
};
}
// keep track of retries
let retries = 0;

return new Promise(resolve => {
//, data: Dispatcher.StreamData)
Expand All @@ -562,6 +565,18 @@ async function downloadAndInstallGithubAsset(

if (code >= 400) {
if (code === HTTP_STATUS_UNAUTHORIZED) {
retries++;
if (retries > 2) {
Logger.error(
LoggerSource.downloader,
`Downloading ${logName} failed. Multiple ` + STATUS_CODES[code]
);
resolve(false);

return;
}
// githubApiUnauthorized will take care of removing the
// token so it isn't used in retry attpemt
githubApiUnauthorized()
.then(() => {
client.stream(
Expand All @@ -573,6 +588,12 @@ async function downloadAndInstallGithubAsset(
.catch(() => {
resolve(false);
});
} else if (code === HTTP_STATUS_FORBIDDEN) {
Logger.error(
LoggerSource.downloader,
`Downloading ${logName} failed: ` + STATUS_CODES[code]
);
resolve(false);
}
//return reject(new Error(STATUS_CODES[code]));
Logger.error(
Expand Down
44 changes: 43 additions & 1 deletion src/utils/githubREST.mts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import GithubApiCache, {
} from "./githubApiCache.mjs";
import { type RequestOptions, request } from "https";
import { unknownErrorToString, unknownToError } from "./errorHelper.mjs";
import { window } from "vscode";
import { env, Uri, window } from "vscode";

// TODO: move into web consts
export const HTTP_STATUS_OK = 200;
export const HTTP_STATUS_NOT_MODIFIED = 304;
export const HTTP_STATUS_UNAUTHORIZED = 401;
export const HTTP_STATUS_FORBIDDEN = 403;
export const EXT_USER_AGENT = "Raspberry Pi Pico VS Code Extension";
export const GITHUB_API_BASE_URL = "https://api.github.com";
export const GITHUB_API_VERSION = "2022-11-28";
Expand Down Expand Up @@ -247,6 +248,12 @@ async function getReleases(repository: GithubRepository): Promise<string[]> {
await githubApiUnauthorized();

return getReleases(repository);
} else if (response.status === HTTP_STATUS_FORBIDDEN) {
githubApiForbidden();

// return the default response as without a PAT
// ther is no way a rerun will succeed in the near future
throw new Error("GitHub API Code 403 Forbidden");
} else if (response.status !== 200) {
throw new Error("Error http status code: " + response.status);
}
Expand Down Expand Up @@ -359,6 +366,12 @@ export async function getGithubReleaseByTag(
await githubApiUnauthorized();

return getGithubReleaseByTag(repository, tag);
} else if (response.status === HTTP_STATUS_FORBIDDEN) {
githubApiForbidden();

// return the default response as without a PAT
// ther is no way a rerun will succeed in the near future
throw new Error("GitHub API Code 403 Forbidden");
} else if (response.status !== 200) {
throw new Error("Error http status code: " + response.status);
}
Expand Down Expand Up @@ -418,3 +431,32 @@ export async function githubApiUnauthorized(): Promise<void> {
);
await Settings.getInstance()?.updateGlobal(SettingsKey.githubToken, "");
}

/**
* Show rate limit exceeded warning to the user.
*/
export function githubApiForbidden(): void {
Logger.warn(
LoggerSource.githubRestApi,
"GitHub API Code 403 Forbidden. Probably rate limit exceeded."
);
// show a rate limit warning to the user
void window
.showWarningMessage(
"GitHub API rate limit exceeded. Please try again later." +
"Consider adding a GitHub Personal Access Token in the settings " +
"to increase your rate limit.",
"More Info"
)
.then(selection => {
if (selection === "More Info") {
env.openExternal(
Uri.parse(
"https://github.com/raspberrypi/pico-vscode" +
"/?tab=readme-ov-file#github-api-rate-limit-error-" +
"while-retrieving-sdk-and-toolchain-versions"
)
);
}
});
}
6 changes: 3 additions & 3 deletions src/webview/newProjectPanel.mts
Original file line number Diff line number Diff line change
Expand Up @@ -911,7 +911,7 @@ export class NewProjectPanel {
increment: 100,
});
await window.showErrorMessage(
"Failed to get ninja version for the selected Pico-SDK version."
"Failed to get ninja version for the selected Pico SDK version."
);

return;
Expand Down Expand Up @@ -1179,7 +1179,7 @@ export class NewProjectPanel {
await this._updateTheme();
} else {
void window.showErrorMessage(
"Failed to load available Pico-SDKs and/or supported toolchains. This may be due to an outdated personal access token for GitHub."
"Failed to load available Pico SDKs and/or supported toolchains. This may be due to an outdated personal access token for GitHub or a exceeded rate limit."
);
this.dispose();
}
Expand Down Expand Up @@ -1615,7 +1615,7 @@ export class NewProjectPanel {
</div>
<div class="grid gap-6 md:grid-cols-2 mt-6">
<div>
<label for="sel-pico-sdk" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Select Pico-SDK version</label>
<label for="sel-pico-sdk" class="block mb-2 text-sm font-medium text-gray-900 dark:text-white">Select Pico SDK version</label>
<select id="sel-pico-sdk" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500">
${picoSDKsHtml}
</select>
Expand Down

0 comments on commit ca4bce8

Please sign in to comment.