refactor: improve error response for non-available models (#298)
This commit is contained in:
committed by
GitHub
parent
694c242865
commit
2031c67d46
42
scripts/system-check.test.ts
Normal file
42
scripts/system-check.test.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
import { describe, expect, test } from 'bun:test'
|
||||
|
||||
import { formatReachabilityFailureDetail } from './system-check.ts'
|
||||
|
||||
describe('formatReachabilityFailureDetail', () => {
|
||||
test('returns generic failure detail for non-codex transport', () => {
|
||||
const detail = formatReachabilityFailureDetail(
|
||||
'https://api.openai.com/v1/models',
|
||||
429,
|
||||
'{"error":"rate_limit"}',
|
||||
{
|
||||
transport: 'chat_completions',
|
||||
requestedModel: 'gpt-4o',
|
||||
resolvedModel: 'gpt-4o',
|
||||
},
|
||||
)
|
||||
|
||||
expect(detail).toBe(
|
||||
'Unexpected status 429 from https://api.openai.com/v1/models. Body: {"error":"rate_limit"}',
|
||||
)
|
||||
})
|
||||
|
||||
test('adds alias/entitlement hint for codex model support 400s', () => {
|
||||
const detail = formatReachabilityFailureDetail(
|
||||
'https://chatgpt.com/backend-api/codex/responses',
|
||||
400,
|
||||
'{"detail":"The \\"gpt-5.3-codex-spark\\" model is not supported when using Codex with a ChatGPT account."}',
|
||||
{
|
||||
transport: 'codex_responses',
|
||||
requestedModel: 'codexspark',
|
||||
resolvedModel: 'gpt-5.3-codex-spark',
|
||||
},
|
||||
)
|
||||
|
||||
expect(detail).toContain(
|
||||
'model alias "codexspark" resolved to "gpt-5.3-codex-spark"',
|
||||
)
|
||||
expect(detail).toContain(
|
||||
'Try "codexplan" or another entitled Codex model.',
|
||||
)
|
||||
})
|
||||
})
|
||||
@@ -58,6 +58,31 @@ function parseOptions(argv: string[]): CliOptions {
|
||||
return options
|
||||
}
|
||||
|
||||
export function formatReachabilityFailureDetail(
|
||||
endpoint: string,
|
||||
status: number,
|
||||
responseBody: string,
|
||||
request: {
|
||||
transport: string
|
||||
requestedModel: string
|
||||
resolvedModel: string
|
||||
},
|
||||
): string {
|
||||
const compactBody = responseBody.trim().replace(/\s+/g, ' ').slice(0, 240)
|
||||
const base = `Unexpected status ${status} from ${endpoint}.`
|
||||
const bodySuffix = compactBody ? ` Body: ${compactBody}` : ''
|
||||
|
||||
if (request.transport !== 'codex_responses' || status !== 400) {
|
||||
return `${base}${bodySuffix}`
|
||||
}
|
||||
|
||||
if (!/not supported.*chatgpt account/i.test(responseBody)) {
|
||||
return `${base}${bodySuffix}`
|
||||
}
|
||||
|
||||
return `${base}${bodySuffix} Hint: model alias "${request.requestedModel}" resolved to "${request.resolvedModel}", which this ChatGPT account does not currently allow. Try "codexplan" or another entitled Codex model.`
|
||||
}
|
||||
|
||||
function checkNodeVersion(): CheckResult {
|
||||
const raw = process.versions.node
|
||||
const major = Number(raw.split('.')[0] ?? '0')
|
||||
@@ -284,6 +309,7 @@ async function checkBaseUrlReachability(): Promise<CheckResult> {
|
||||
headers['chatgpt-account-id'] = credentials.accountId
|
||||
}
|
||||
headers['Content-Type'] = 'application/json'
|
||||
headers.originator = 'openclaude'
|
||||
method = 'POST'
|
||||
body = JSON.stringify({
|
||||
model: request.resolvedModel,
|
||||
@@ -315,7 +341,17 @@ async function checkBaseUrlReachability(): Promise<CheckResult> {
|
||||
return pass('Provider reachability', `Reached ${endpoint} (status ${response.status}).`)
|
||||
}
|
||||
|
||||
return fail('Provider reachability', `Unexpected status ${response.status} from ${endpoint}.`)
|
||||
const responseBody = await response.text().catch(() => '')
|
||||
const detail = formatReachabilityFailureDetail(
|
||||
endpoint,
|
||||
response.status,
|
||||
responseBody,
|
||||
request,
|
||||
)
|
||||
return fail(
|
||||
'Provider reachability',
|
||||
detail,
|
||||
)
|
||||
} catch (error) {
|
||||
const message = error instanceof Error ? error.message : String(error)
|
||||
return fail('Provider reachability', `Failed to reach ${endpoint}: ${message}`)
|
||||
@@ -504,6 +540,8 @@ async function main(): Promise<void> {
|
||||
}
|
||||
}
|
||||
|
||||
await main()
|
||||
if (import.meta.main) {
|
||||
await main()
|
||||
}
|
||||
|
||||
export {}
|
||||
|
||||
Reference in New Issue
Block a user