diff --git a/lib/github_changelog_generator/octo_fetcher.rb b/lib/github_changelog_generator/octo_fetcher.rb index 27ee894..6d0db33 100644 --- a/lib/github_changelog_generator/octo_fetcher.rb +++ b/lib/github_changelog_generator/octo_fetcher.rb @@ -8,6 +8,7 @@ module GitHubChangelogGenerator class OctoFetcher PER_PAGE_NUMBER = 100 MAX_THREAD_NUMBER = 25 + MAX_FORBIDDEN_RETRIES = 100 CHANGELOG_GITHUB_TOKEN = "CHANGELOG_GITHUB_TOKEN" GH_RATE_LIMIT_EXCEEDED_MSG = "Warning: Can't finish operation: GitHub API rate limit exceeded, change log may be " \ "missing some issues. You can limit the number of issues fetched using the `--max-issues NUM` argument." @@ -285,22 +286,33 @@ Make sure, that you push tags to remote repo via 'git push --tags'" value = yield rescue Octokit::Unauthorized => e Helper.log.error e.message - abort "Error: wrong GitHub token" + sys_abort("Error: wrong GitHub token") rescue Octokit::Forbidden => e attempt += 1 sleep_time = exp_backoff(attempt) Helper.log.warn("sleeping #{sleep_time} second") - sleep(sleep_time) + sys_sleep(sleep_time) Helper.log.warn e.message Helper.log.warn GH_RATE_LIMIT_EXCEEDED_MSG Helper.log.warn @client.rate_limit - retry + if attempt >= MAX_FORBIDDEN_RETRIES + sys_abort("Exceeded retry limit") + else + retry + end end value end + def sys_sleep(seconds) + sleep(seconds) + end + + def sys_abort(msg) + abort(msg) + end # Returns the exponential backoff (seconds) for this attempt number # # @param [Integer] attempt the attempt number diff --git a/spec/unit/octo_fetcher_spec.rb b/spec/unit/octo_fetcher_spec.rb index f74e25f..14dd244 100644 --- a/spec/unit/octo_fetcher_spec.rb +++ b/spec/unit/octo_fetcher_spec.rb @@ -12,6 +12,32 @@ describe GitHubChangelogGenerator::OctoFetcher do let(:fetcher) { GitHubChangelogGenerator::OctoFetcher.new(options) } + describe "#check_github_response" do + context "when returns successfully" do + it "returns block value" do + expect(fetcher.send(:check_github_response) { 1+1 }).to eq(2) + end + end + + context "when raises Octokit::Unauthorized" do + it "aborts" do + expect(fetcher).to receive(:sys_abort).with("Error: wrong GitHub token") + fetcher.send(:check_github_response) { raise(Octokit::Unauthorized) } + end + end + + context "when raises Octokit::Forbidden" do + it "sleeps and retries and then aborts" do + retry_limit = GitHubChangelogGenerator::OctoFetcher::MAX_FORBIDDEN_RETRIES - 1 + + expect(fetcher).to receive(:sys_abort).with("Exceeded retry limit") + expect(fetcher).to receive(:sys_sleep).exactly(retry_limit).times + fetcher.send(:check_github_response) { raise(Octokit::Forbidden) } + end + end + + end + describe "#fetch_github_token" do token = GitHubChangelogGenerator::OctoFetcher::CHANGELOG_GITHUB_TOKEN context "when token in ENV exist" do