← Public packages
@kentcdodds/lineage
Interactive commit-level lines of kody, minus generated noise, as an offline-ready chart.
src/github-errors.node.test.ts
71 lines · 2.2 KB · TypeScriptimport assert from 'node:assert/strict'
import test from 'node:test'
import {
githubFailureStatus,
isTransientGithubFailure,
withTransientGithubRetry,
} from './github-errors.ts'
function requestError(status: number, message = `GitHub request failed with ${status} `) {
const error = new Error(message) as Error & { response: { status: number } }
error.name = 'GitHubRequestError'
error.response = { status }
return error
}
test('reads status from GitHubRequestError.response', () => {
assert.equal(githubFailureStatus(requestError(522)), 522)
assert.equal(githubFailureStatus(requestError(404)), 404)
})
test('falls back to the github helper message format', () => {
assert.equal(githubFailureStatus(new Error('GitHub request failed with 503 ')), 503)
assert.equal(githubFailureStatus(new Error('unrelated failure')), null)
assert.equal(githubFailureStatus('not-an-error'), null)
})
test('treats Cloudflare and GitHub blips as transient', () => {
assert.equal(isTransientGithubFailure(requestError(522)), true)
assert.equal(isTransientGithubFailure(requestError(502)), true)
assert.equal(isTransientGithubFailure(requestError(429)), true)
const timeout = new Error('GitHub request timed out: https://api.github.com/repos/o/r/commits')
timeout.name = 'GitHubRequestTimeoutError'
assert.equal(isTransientGithubFailure(timeout), true)
})
test('does not treat caller or not-found failures as transient', () => {
assert.equal(isTransientGithubFailure(requestError(404)), false)
assert.equal(isTransientGithubFailure(requestError(401)), false)
assert.equal(isTransientGithubFailure(requestError(403)), false)
assert.equal(isTransientGithubFailure(new Error('boom')), false)
})
test('retries a transient failure once, then succeeds', async () => {
let calls = 0
const result = await withTransientGithubRetry(
async () => {
calls += 1
if (calls === 1) throw requestError(522)
return 'ok'
},
{ delayMs: 0 },
)
assert.equal(result, 'ok')
assert.equal(calls, 2)
})
test('does not retry a non-transient failure', async () => {
let calls = 0
await assert.rejects(
() =>
withTransientGithubRetry(
async () => {
calls += 1
throw requestError(404)
},
{ delayMs: 0 },
),
/GitHub request failed with 404/,
)
assert.equal(calls, 1)
})