-
Notifications
You must be signed in to change notification settings - Fork 23
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using paginate with the retry plugin #33
Comments
The
Very interesting, I've never run into this myself or heard about this behavior before. If that is in fact a common problem, then I think we should build handling for it into the Could you maybe share more of your code? Or could whoever you talked to from GitHub comment here with some more insights? They can also contact me in the internal GitHub Slack if that works better
|
Thanks for looking into this. I've fixed the runkit example to show that I don't think paginate is using the retry plugin. Here is the output: The paginate call fails after 1 call not after the 3 retries that the request call did if you look at the timings of the log entries. I wonder if the perhaps I'm getting the wrong parameters to paginate to enable the retry plugin for that call? Here is some code with which I was able to reproduce the authentication issue that sent me down the retry route this morning, took a couple of minutes till it failed though. (async () => {
try {
const { Octokit } = require('@octokit/core')
const { paginateRest } = require('@octokit/plugin-paginate-rest')
const { enterpriseCloud } = require('@octokit/plugin-enterprise-cloud')
const { retry } = require('@octokit/plugin-retry')
const { createAppAuth } = require('@octokit/auth-app')
const auth = createAppAuth({
id: process.env.GITHUBAPPID,
privateKey: process.env.GITHUBPRIVATEKEY.replace(/\\n/g, '\n') // Replace there as newlines get messed up by keychain, but just a standard pem file
})
const installationAuthentication = await auth({ type: 'installation', installationId: 12345, refresh: true })
const PluginOctokit = Octokit.plugin(paginateRest, enterpriseCloud, retry)
const octokit = new PluginOctokit({
auth: installationAuthentication.token
})
const credentials = await octokit.paginate('GET /orgs/:org/credential-authorizations', {
org: 'org-with-saml-enabled',
per_page: 10
})
console.log(credentials.length)
} catch (error) {
console.log('Error: ', error)
process.exit(1)
}
})() I then just ran the script with: while node test-auth.js; do :; done Which gave the output of (trimmed a bit and sanitised):
What I am doing is "extreme" in that installation tokens aren't being cached, but that it can fail is what I need to recover from. I did also remove the token redaction while testing last week so that I could ensure that the authorization token was being set with the token being generated and that was the case for all of the times I saw failures. I only really spotted this when I was doing work over all of the organisations that had the app installed, although only 5, and would occasionally get one failing, this testing wasn't as extreme as the while loop above, just occasional runs to test some code. I thought it might be an odd caching situation but I did get it at one point when I ran the script the first time so there should be no caching going on at that point. @droidpl is aware of this and there is also a support ticket open with some details (Javier asked me to raise it as they had better access to the logs). The support ticket, 665607, has the following information in it:
And after I queried that (as the documentation does not say that installations token might not work when generated) they replied:
While doing some more investigation I did come across https://gh.neting.ccmunity/t5/GitHub-API-Development-and/Random-401-errors-after-using-freshly-generated-installation/td-p/22905 which gave a similar answer. I did note that both answers so to use exponential backoffs of the retry which isn't something I think the retry plugin does currently. Perhaps we should split this discussion though into two issues if that is easier as the bad credentials is a different issue and probably does belong on the auth-app really. |
Thanks Steve for the extensive reply, much appreciated! I'll investigate the retry/pagination plugins combination first. After that I will investigate the problem with the access tokens |
See my runkit here:
|
Thanks, but I think it still shows the problem? The Also, in my test with the 401 errors the |
it is, the logs is on page 2
Hmmm I'll investigate, thank you for the clarification, I'm sorry I misunderstood you the first time |
Yes, I think you are right. Smells like a bug in the retry plugin to me, I'll investigate further and will keep you posted When I remove the |
OK. I think being able to retry 401s / 404s might be something that is needed as well if the comment from support is correct:
The way that comment reads to me they are saying that not only the installation token issues I am seeing throw 401s, but it could also mean that creating an issue via the api and checking it straight away might return a 404? |
I opened a separate internal issue with GitHub about it. I asked them to document that behavior in the docs, to make it "official". Once it is, I will built handling of that 401 directly into |
If you can let @droidpl know the details of that he can track it as well for us. |
I'm pretty sure that the installation access token delay is what's causing "Bad Credentials" errors for my WIP app, too. I could never find out what was causing them, this is likely it. |
I think this issue can be closed via octokit/auth-app.js#65? |
Can the retry plugin be used for calls that are being used with the paginate plugin?
I'm trying to workaround an issue where GitHub App installation tokens occasionally don't work if used too quickly after they've been created, and GitHub have suggested retrying requests after a short time (error returned by the GitHub API is 401 Bad Authentication). Trying to make use of the retry plugin along with the paginate plugin and it looks like the paginate plugin ignores any settings from the retry plugin when either specified as part of the call to paginate, or when setup on the octokit object.
Tested this by using a bad API url as the 401 error is sporadic so hard to test.
Log output when trying to use the paginate plugin:
Log output when trying to use a normal request:
This is with a retries of 5 and a retryAfter of 5 to make it obvious that retries are happening. The paginate call errors out immediately, the request call errors out over 25 seconds after the before hook is called. So it looks to me like paginate isn't honouring the retry plugin whereas request is?
I've tried to get this running in runkit, https://runkit.com/steve-norman-rft/5ea944308e20c1001ad95df5, but for some reason the paginate plugin is causing an error when it is included:
The error is generated from line 14 of the notebook. If I just use the retry plugin the first test completes as expected with the retries, the second fails as paginate doesn't exist.
The text was updated successfully, but these errors were encountered: