Merge pull request #7676 from lunarway/feature/github-ratelimit

Detect GitHub rate limits in GithubUrlReader
This commit is contained in:
Patrik Oldsberg
2021-10-19 17:00:44 +02:00
committed by GitHub
3 changed files with 43 additions and 1 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/backend-common': patch
---
Add "rate limit exceeded" to error from GithubUrlReader if that is the cause of a read failure
@@ -221,6 +221,32 @@ describe('GithubUrlReader', () => {
).rejects.toThrow(NotModifiedError);
});
it('should throw Error with ratelimit exceeded if GitHub responds with 403 and rate limit is exceeded', async () => {
expect.assertions(1);
worker.use(
rest.get(
'https://ghe.github.com/api/v3/repos/backstage/mock/tree/contents/',
(_req, res, ctx) => {
return res(
ctx.status(403),
ctx.set('X-RateLimit-Remaining', '0'),
ctx.body(
'{"message": "API rate limit exceeded for xxx.xxx.xxx.xxx..."}',
),
);
},
),
);
await expect(
gheProcessor.readUrl(
'https://github.com/backstage/mock/tree/blob/main',
{ etag: 'foo' },
),
).rejects.toThrow(/rate limit exceeded/);
});
it('should return etag from the response', async () => {
(mockCredentialsProvider.getCredentials as jest.Mock).mockResolvedValue({
headers: {
@@ -126,10 +126,21 @@ export class GithubUrlReader implements UrlReader {
};
}
const message = `${url} could not be read as ${ghUrl}, ${response.status} ${response.statusText}`;
let message = `${url} could not be read as ${ghUrl}, ${response.status} ${response.statusText}`;
if (response.status === 404) {
throw new NotFoundError(message);
}
// GitHub returns a 403 response with a couple of headers indicating rate
// limit status. See more in the GitHub docs:
// https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting
if (
response.status === 403 &&
response.headers.get('X-RateLimit-Remaining') === '0'
) {
message += ' (rate limit exceeded)';
}
throw new Error(message);
}