TinkerLab
ARTIFACT // SSE-STREAM-GUARD.MJS (JAVASCRIPT)

抗中断 LLM SSE 流式解析器(捕获 HTTP 200 后的流内报错与截断) (sse-stream-guard.mjs)

解决“HTTP 状态码为 200 但生成中途断流报错”问题:识别流内 error 事件、空闲超时与长度截断。

[核心实测结论 / TL;DR]本配置包「抗中断 LLM SSE 流式解析器(捕获 HTTP 200 后的流内报错与截断)」(文件名:sse-stream-guard.mjs,格式:JAVASCRIPT)是 Tinker AI 实测工坊配套指南《sse-http200-stream-errors》的参数化生产模板。支持在本地浏览器实时定制 流式接口地址 (STREAM_API_URL=http://127.0.0.1:11434/v1/chat/completions)、分块空闲超时阈值 (ms) (IDLE_TIMEOUT_MS=15000) 等 2 项核心变量,默认遵循 127.0.0.1 回环绑定与最小权限规范。
04 // DIAGNOSISAPI 与部署排障· 验证日期:2026-10-23
查看全部 42 套配置附件 →
sse-stream-guard.mjs

抗中断 LLM SSE 流式解析器(捕获 HTTP 200 后的流内报错与截断)

解决“HTTP 状态码为 200 但生成中途断流报错”问题:识别流内 error 事件、空闲超时与长度截断。

查看配套实测指南 →
参数化定制变量 (Variables — 自动保存在本地浏览器)
UTF-8 编码 · 零延迟实时编译
// Tinker AI — Resilient SSE Stream Reader with Mid-Stream Error Detection
const API_URL = "http://127.0.0.1:11434/v1/chat/completions";
const IDLE_TIMEOUT_MS = Number("15000");

export async function consumeLlmStream(payload) {
  const res = await fetch(API_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ ...payload, stream: true }),
  });

  if (!res.ok || !res.body) {
    throw new Error(`Pre-stream HTTP failure: ${res.status}`);
  }

  const reader = res.body.getReader();
  const decoder = new TextDecoder();
  let buffer = "";
  let output = "";

  while (true) {
    const timer = setTimeout(() => reader.cancel("SSE chunk idle timeout"), IDLE_TIMEOUT_MS);
    const { value, done } = await reader.read().finally(() => clearTimeout(timer));
    if (done) break;

    buffer += decoder.decode(value, { stream: true });
    const lines = buffer.split("\n");
    buffer = lines.pop() ?? "";

    for (const raw of lines) {
      const line = raw.trim();
      if (!line.startsWith("data:")) continue;
      const data = line.slice(5).trim();
      if (data === "[DONE]") return { output, completed: true };

      const event = JSON.parse(data);
      // Catch mid-stream error frame sent AFTER HTTP 200 OK
      if (event.error || event.type === "error") {
        throw new Error(`Mid-stream SSE error after HTTP 200: ${ JSON.stringify(event.error || event) }`);
      }
      const delta = event.choices?.[0]?.delta?.content ?? "";
      output += delta;
    }
  }
  return { output, completed: false };
}
PARAMETER SPECIFICATION // 参数化变量规范说明表

「sse-stream-guard.mjs」可定制环境变量与默认值说明

本配置模板(JAVASCRIPT 格式)支持 2 项运行时参数注入,所有替换均在本地浏览器内完成。

模板占位符参数用途说明安全默认值填写示例
{{STREAM_API_URL}}流式接口地址http://127.0.0.1:11434/v1/chat/completionshttp://127.0.0.1:11434/v1/chat/completions
{{IDLE_TIMEOUT_MS}}分块空闲超时阈值 (ms)1500015000
PAIRED HARDWARE MANIFEST // 配套实测环境与边界记录

配套指南《LLM API 在 HTTP 200 后流式报错:错误发生条件与恢复边界》验证基线

实测硬件与操作系统 (Hardware & OS)

Node.js 22.13+ 流式客户端 · 适用于 Claude API、OpenAI 兼容接口及本地 Ollama / vLLM

锁定软件栈与模型版本 (Pinned Versions)
Node.js 22.13+Anthropic Messages SSEOpenAI Chat Completions SSE
离线与安全边界 (同时适用于本地与云端流式 API)

配套抗中断 SSE 解析器代码,可在本地零成本验证流内异常捕获与超时取消逻辑。

已知限制与失败边界 (Known Limits)
  • 正如 Claude 官方文档明确指出的:SSE 流式响应一旦发出 HTTP 200 响应头,生成中途发生的过载、OOM 或超时错误已无法修改 HTTP 状态码,只能通过流内 error 事件下发。
  • 当流式响应在生成中途断流时,若对已触发下游写操作的请求无脑重试而未校验幂等键,会导致重复入库或重复发送通知。
DEPLOYMENT CHECKLIST // 配置落地核验步骤

部署 sse-stream-guard.mjs 后的 3 步验收清单

  1. 确认流式客户端在消费每个数据帧时均检查了 `event.error` 字段。
  2. 确认客户端在保存结构化结果前强制校验 `[DONE]` 标志与 `finish_reason === "stop"`。
  3. 已为分块读取配置空闲超时(`reader.cancel`),防止反向代理静默断流导致协程永久挂起。