yikart/AiToEarn · error · Error

HTTP ${response.status}

Error message

HTTP ${response.status}

What it means

thrown by the SSE onopen handler in ai.api.ts for any status not in the 4xx-client-error band (or 429) — i.e. 5xx server errors or abnormal statuses. Unlike the client-error branch it contains no response body, only the numeric status. Signals the backend/stream gateway failed rather than the request being malformed.

Source

Thrown at project/aitoearn-web/src/api/ai/ai.api.ts:136

        openWhenHidden: true,

        // 当连接打开时
        async onopen(response) {
          if (response.ok) {
            return // 一切正常,继续处理消息
          }

          // 处理错误响应
          if (response.status >= 400 && response.status < 500 && response.status !== 429) {
            // 客户端错误,不重试
            const errorText = await response.text()
            console.error('[SSE] Client error:', response.status, errorText)
            throw new Error(`HTTP ${response.status}: ${errorText}`)
          }
          else {
            // 服务器错误或其他问题,不自动重试,直接抛出错误
            console.error('[SSE] Server error:', response.status)
            throw new Error(`HTTP ${response.status}`)
          }
        },

        // 当收到消息时
        onmessage(event) {
          // 如果已完成,忽略后续消息
          if (isCompleted) {
            return
          }

          // 如果没有数据,跳过
          if (!event.data) {
            return
          }

          try {
            const data = JSON.parse(event.data)

View on GitHub (pinned to d3aa8bea5b)

Solutions

  1. Check backend logs at the corresponding timestamp for the 5xx root cause.
  2. Retry the request after a short delay — server errors are often transient (and 429 is already treated as retryable).
  3. Increase gateway/proxy read timeouts for SSE endpoints to avoid 504 on long streams.
  4. Add status-based user messaging in the UI ('服务暂时不可用,请稍后重试').

Example fix

// before
throw new Error(`HTTP ${response.status}`)
// after
if (response.status >= 500) return retryWithBackoff() // caller-level retry
throw new Error(`HTTP ${response.status}`)
Defensive patterns

Strategy: retry

Validate before calling

// probe backend health before opening the stream
const health = await fetch('/api/health').then(r => r.ok).catch(() => false)
if (!health) throw new Error('AI 服务暂不可用')

Type guard

function isServerHttpError(e: unknown): e is Error {
  return e instanceof Error && /^HTTP 5\d\d$/.test(e.message)
}

Try / catch

try {
  await openAiSseStream(params)
}
catch (e) {
  if (e instanceof Error && /^HTTP 5\d\d$/.test(e.message)) {
    await retryWithBackoff(() => openAiSseStream(params), { attempts: 3 })
  }
  else throw e
}

Prevention

When it happens

Trigger: Opening an AI SSE stream while the backend returns 500/502/503/504 — e.g. upstream LLM provider outage, backend crash, gateway timeout, or service being restarted.

Common situations: LLM provider quota/outage causing backend 5xx; deployment or rolling restart mid-stream; nginx/gateway timeout (502/504) on long-lived SSE connections; overloaded AI service.

Related errors


AI-assisted analysis of yikart/AiToEarn@d3aa8bea5b (2026-08-31). Data as JSON: /api/errors/277f88380167fecc. Report an issue: GitHub.