Keep a page error or a busy engine from blanking the app

A user on Upload got a white page while the engine's proxy answered
many requests with nginx's rate-limit 503.

- Pages render inside an error boundary, so a crash shows a message
  with Try again and Reload instead of unmounting the whole app.
- A 503 or 429 without the engine's JSON reads "The engine is busy",
  and queries wait 5s, then 10s, before asking again instead of 1s.
- Upload asks for knowledge details two at a time and reuses them
  until the document's knowledge status changes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Iqbal
2026-10-29 18:38:18 +07:00
parent a47fe0f845
commit dfb3275afe
8 changed files with 97 additions and 5 deletions

19
src/api/client.test.ts Normal file
View File

@@ -0,0 +1,19 @@
import { describe, expect, it } from 'vitest'
import { limiter } from './client'
describe('limiter', () => {
it('runs at most n calls at once, all of them, failures included', async () => {
const limit = limiter(2)
let running = 0, peak = 0
const call = (n: number) => limit(async () => {
peak = Math.max(peak, ++running)
await new Promise(r => setTimeout(r, 5))
running--
if (n === 2) throw new Error('503')
return n
})
const out = await Promise.allSettled([1, 2, 3, 4, 5].map(call))
expect(peak).toBe(2)
expect(out.map(r => (r.status === 'fulfilled' ? r.value : 'x'))).toEqual([1, 'x', 3, 4, 5])
})
})