fix: close recovery review gaps
This commit is contained in:
@@ -35,7 +35,10 @@ function classifyPiAiError(message: string): string {
|
||||
if (/\b400\b|invalid.?request/i.test(message)) return 'INVALID_REQUEST'
|
||||
if (/\b5\d\d\b/.test(message)) return 'SERVER'
|
||||
if (/\btime(?:d)?\s*out\b|timeout/i.test(message)) return 'TIMEOUT'
|
||||
if (/\b(?:network|connection|socket|fetch)\b|\bECONN[A-Z]+\b/i.test(message)) return 'TRANSPORT'
|
||||
if (/\b(?:network|connection|socket|fetch)\b|\bECONN[A-Z]+\b/i.test(message)
|
||||
|| /\b(?:other side closed|HTTP2 request did not get a response|WebSocket closed unexpectedly)\b/i.test(message)) {
|
||||
return 'TRANSPORT'
|
||||
}
|
||||
return 'PI_AI_ERROR'
|
||||
}
|
||||
|
||||
|
||||
@@ -535,6 +535,10 @@ describe('mapStopReason / mapUsage', () => {
|
||||
.toMatchObject({ kind: 'error', failure: { code: 'RATE_LIMIT' } })
|
||||
expect(mapStopReason(assistant({ stopReason: 'error', errorMessage: 'HTTP 429: insufficient_quota' })))
|
||||
.toMatchObject({ kind: 'error', failure: { code: 'QUOTA' } })
|
||||
expect(mapStopReason(assistant({
|
||||
stopReason: 'error',
|
||||
errorMessage: 'OpenAI API error (429): You exceeded your current quota, please check your plan and billing details.',
|
||||
}))).toMatchObject({ kind: 'error', failure: { code: 'QUOTA' } })
|
||||
expect(mapStopReason(assistant({ stopReason: 'error', errorMessage: 'HTTP 500: backend down' })))
|
||||
.toMatchObject({ kind: 'error', failure: { code: 'SERVER' } })
|
||||
expect(mapStopReason(assistant({ stopReason: 'error', errorMessage: 'provider timed out' })))
|
||||
@@ -555,6 +559,15 @@ describe('mapStopReason / mapUsage', () => {
|
||||
}))).toMatchObject({ kind: 'error', failure: { code: 'INVALID_REQUEST' } })
|
||||
})
|
||||
|
||||
it.each([
|
||||
'other side closed',
|
||||
'HTTP2 request did not get a response',
|
||||
'WebSocket closed unexpectedly',
|
||||
])('maps pi-ai transport wording %j', (errorMessage) => {
|
||||
expect(mapStopReason(assistant({ stopReason: 'error', errorMessage })))
|
||||
.toMatchObject({ kind: 'error', failure: { code: 'TRANSPORT' } })
|
||||
})
|
||||
|
||||
it('uses pi-ai provider-specific overflow classification without losing rate-limit exclusions', () => {
|
||||
expect(mapStopReason(assistant({
|
||||
stopReason: 'error',
|
||||
|
||||
@@ -74,6 +74,7 @@ export function isContextWindowExceededError(detail: string): boolean {
|
||||
export function isQuotaExceededError(detail: string): boolean {
|
||||
return /\binsufficient[\s_-]+(?:quota|balance|credits?)\b/i.test(detail)
|
||||
|| /\b(?:quota|usage[\s_-]+limit)[\s_-]+(?:exceeded|exhausted|reached)\b/i.test(detail)
|
||||
|| /\bexceed(?:ed|s)?[\s_-]+(?:(?:your|the)[\s_-]+)?(?:current[\s_-]+)?quota\b/i.test(detail)
|
||||
|| /\b(?:balance|credits?)[\s_-]+(?:exhausted|depleted)\b/i.test(detail)
|
||||
|| /\bout[\s_-]+of[\s_-]+(?:credits?|budget)\b/i.test(detail)
|
||||
}
|
||||
|
||||
@@ -90,6 +90,7 @@ describe('LlmService', () => {
|
||||
'account balance depleted',
|
||||
'usage-limit-exceeded',
|
||||
'out of credits',
|
||||
'OpenAI API error (429): You exceeded your current quota, please check your plan and billing details.',
|
||||
]) expect(isQuotaExceededError(detail)).toBe(true)
|
||||
expect(isQuotaExceededError('HTTP 429: rate limit reached')).toBe(false)
|
||||
expect(isQuotaExceededError('quota resets in one minute')).toBe(false)
|
||||
|
||||
Reference in New Issue
Block a user