mirror of
https://github.com/stablyai/orca.git
synced 2026-10-18 00:03:20 +00:00
fix(github): preserve outage attribution edge cases
This commit is contained in:
@@ -6322,6 +6322,32 @@ describe('createGitHubSlice.fetchWorkItems source/error envelope', () => {
|
||||
}
|
||||
})
|
||||
|
||||
it('ignores an ineligible SSH repo when every GitHub source is unavailable', async () => {
|
||||
const store = createTestStore()
|
||||
const consoleWarn = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
||||
mockApi.gh.listWorkItems
|
||||
.mockRejectedValueOnce(new Error(GITHUB_WORK_ITEMS_SSH_REMOTE_REQUIRED_MESSAGE))
|
||||
.mockRejectedValueOnce(new Error('HTTP 503: Service Unavailable'))
|
||||
|
||||
try {
|
||||
const result = await store.getState().fetchWorkItemsAcrossRepos(
|
||||
[
|
||||
{ repoId: 'ssh-repo', path: '/server/ssh-repo' },
|
||||
{ repoId: 'github-repo', path: '/server/github-repo' }
|
||||
],
|
||||
24,
|
||||
100,
|
||||
''
|
||||
)
|
||||
|
||||
expect(result.items).toEqual([])
|
||||
expect(result.failedCount).toBe(1)
|
||||
expect(result.githubUnavailable).toBe(true)
|
||||
} finally {
|
||||
consoleWarn.mockRestore()
|
||||
}
|
||||
})
|
||||
|
||||
it('keeps the partial-failure count when another GitHub repo still loads', async () => {
|
||||
const store = createTestStore()
|
||||
const consoleWarn = vi.spyOn(console, 'warn').mockImplementation(() => {})
|
||||
|
||||
@@ -2866,6 +2866,7 @@ export const createGitHubSlice: StateCreator<AppState, [], [], GitHubSlice> = (s
|
||||
const state = get()
|
||||
let failedCount = 0
|
||||
let unavailableFailureCount = 0
|
||||
let skippedSourceCount = 0
|
||||
const perProjectResults = await Promise.all(
|
||||
repos.map(async (r) => {
|
||||
try {
|
||||
@@ -2881,6 +2882,7 @@ export const createGitHubSlice: StateCreator<AppState, [], [], GitHubSlice> = (s
|
||||
// Why: must use perRepoLimit (not displayLimit) so the cache key
|
||||
// matches what fetchWorkItems wrote.
|
||||
if (isGitHubWorkItemsSshRemoteRequiredError(err)) {
|
||||
skippedSourceCount += 1
|
||||
return [] as GitHubWorkItem[]
|
||||
}
|
||||
const key =
|
||||
@@ -2911,10 +2913,12 @@ export const createGitHubSlice: StateCreator<AppState, [], [], GitHubSlice> = (s
|
||||
const merged = sortWorkItemsByNumber(perProjectResults.flat()).slice(0, displayLimit)
|
||||
// Why: one repo can fail with a 5xx while another succeeds (or fails for a
|
||||
// permission reason). Only claim a global availability failure when every
|
||||
// selected repo failed for a GitHub reachability reason; otherwise keep the
|
||||
// exact count.
|
||||
// eligible source failed for a GitHub reachability reason; intentionally
|
||||
// skipped SSH repos are not GitHub sources for this calculation.
|
||||
const githubUnavailable =
|
||||
failedCount > 0 && failedCount === repos.length && unavailableFailureCount === failedCount
|
||||
failedCount > 0 &&
|
||||
failedCount === repos.length - skippedSourceCount &&
|
||||
unavailableFailureCount === failedCount
|
||||
return { items: merged, failedCount, githubUnavailable }
|
||||
},
|
||||
|
||||
|
||||
@@ -18,6 +18,8 @@ describe('classifyGitHubUnavailable', () => {
|
||||
'request to https://api.github.com failed, reason: getaddrinfo ENOTFOUND api.github.com',
|
||||
'dial tcp: lookup api.github.com: no such host',
|
||||
'connect ETIMEDOUT 140.82.112.5:443',
|
||||
'TimeoutError: request aborted',
|
||||
'NetworkError when attempting to fetch resource',
|
||||
'fetch failed',
|
||||
'socket hang up',
|
||||
'could not resolve host: api.github.com',
|
||||
|
||||
@@ -23,7 +23,7 @@ const SERVER_ERROR_PATTERN =
|
||||
// both Node (ENOTFOUND/ECONNRESET) and the gh Go client ("dial tcp", "i/o
|
||||
// timeout", "no such host") shapes.
|
||||
const NETWORK_PATTERN =
|
||||
/\btimeout\b|\btimed out\b|\bno such host\b|could not resolve host|could not resolve to a host|\bnetwork\b|\bconnection (?:refused|reset)\b|\bdial tcp\b|\bi\/o timeout\b|\bfetch failed\b|\bsocket hang up\b|ENOTFOUND|ECONNRESET|ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|ENETUNREACH/i
|
||||
/timeout|\btimed out\b|\bno such host\b|could not resolve host|could not resolve to a host|network|\bconnection (?:refused|reset)\b|\bdial tcp\b|\bi\/o timeout\b|\bfetch failed\b|\bsocket hang up\b|ENOTFOUND|ECONNRESET|ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|ENETUNREACH/i
|
||||
|
||||
/**
|
||||
* Classify a gh/Octokit error message as a GitHub-reachability problem, or
|
||||
|
||||
Reference in New Issue
Block a user