-
Notifications
You must be signed in to change notification settings - Fork 281
Expand file tree
/
Copy pathGet-MtGitHubRateLimitMessage.ps1
More file actions
75 lines (66 loc) · 3.51 KB
/
Copy pathGet-MtGitHubRateLimitMessage.ps1
File metadata and controls
75 lines (66 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
function Get-MtGitHubRateLimitMessage {
<#
.SYNOPSIS
Internal: Returns a GitHub rate-limit message for an ErrorRecord, or $null when the
error is not a rate-limit response.
.DESCRIPTION
Mirrors the rate-limit detection in Invoke-MtGitHubRequest so that bootstrap callers
(Connect-MtGitHub) can distinguish HTTP 403/429 caused by rate limiting from
permission, token, or org-access failures.
Returns:
- "GitHub API rate limit encountered (HTTP <code>). Resets at: <time>" when the
response carries x-ratelimit-remaining = 0 (primary rate limit).
- "GitHub secondary rate limit encountered (HTTP <code>). Retry after: <n>s" when
the response carries retry-after (secondary rate limit / abuse detection).
- "GitHub secondary rate limit encountered (HTTP <code>). Retry after at least 60s."
when the response body indicates secondary-limit / abuse-detection wording but
no retry-after header is present.
- $null for any other error, including 403/429 without rate-limit headers.
#>
param(
[Parameter(Mandatory)] $ErrorRecord
)
$code = Get-MtGitHubErrorStatusCode -ErrorRecord $ErrorRecord
if ($code -notin 403, 429) { return $null }
$response = $null
try {
if ($null -ne $ErrorRecord.Exception) { $response = $ErrorRecord.Exception.Response }
} catch {
Write-Debug "Get-MtGitHubRateLimitMessage: $($_.Exception.Message)"
}
if ($null -eq $response) { return $null }
$headers = $null
try { $headers = $response.Headers } catch {
Write-Debug "Get-MtGitHubRateLimitMessage headers: $($_.Exception.Message)"
}
if ($null -eq $headers) { return $null }
$remaining = Get-MtGitHubResponseHeaderValue -Headers $headers -Name 'x-ratelimit-remaining'
$remainingValue = 0
$remainingParsed = $null -ne $remaining -and [int]::TryParse([string]$remaining, [ref]$remainingValue)
if ($remainingParsed -and $remainingValue -eq 0) {
$reset = Get-MtGitHubResponseHeaderValue -Headers $headers -Name 'x-ratelimit-reset'
$resetSeconds = 0L
$resetTime = 'unknown'
if ($null -ne $reset -and [long]::TryParse([string]$reset, [ref]$resetSeconds)) {
try { $resetTime = [DateTimeOffset]::FromUnixTimeSeconds($resetSeconds).LocalDateTime } catch {
Write-Debug "Get-MtGitHubRateLimitMessage reset conversion: $($_.Exception.Message)"
}
}
return "GitHub API rate limit encountered (HTTP $code). Resets at: $resetTime"
}
$retryAfter = Get-MtGitHubResponseHeaderValue -Headers $headers -Name 'retry-after'
if ($null -ne $retryAfter) {
return "GitHub secondary rate limit encountered (HTTP $code). Retry after: ${retryAfter}s"
}
# Some secondary-limit responses omit retry-after entirely (e.g. older abuse-detection
# responses, or responses where the proxy strips the header). Fall back to body wording -
# GitHub's documented messages include phrases like "secondary rate limit" and
# "abuse detection mechanism". When matched, recommend the 60-second minimum backoff
# documented at https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api.
$bodyMessage = Get-MtGitHubErrorMessage -ErrorRecord $ErrorRecord
if (-not [string]::IsNullOrEmpty($bodyMessage) -and
$bodyMessage -match '(?i)secondary\s+rate\s+limit|abuse\s+detection') {
return "GitHub secondary rate limit encountered (HTTP $code). Retry after at least 60s."
}
return $null
}