feat(open-sse): non-streaming stream-error pattern match → 502 fallback
This commit is contained in:
75
tests/unit/sse-error-patterns.test.js
Normal file
75
tests/unit/sse-error-patterns.test.js
Normal file
@@ -0,0 +1,75 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { handleForcedSSEToJson } from "../../open-sse/handlers/chatCore/sseToJsonHandler.js";
|
||||
|
||||
const encoder = new TextEncoder();
|
||||
const sseResponse = (chunks) => {
|
||||
const body = new ReadableStream({
|
||||
start(c) {
|
||||
for (const ch of chunks) c.enqueue(encoder.encode(`data: ${JSON.stringify(ch)}\n\n`));
|
||||
c.enqueue(encoder.encode("data: [DONE]\n\n"));
|
||||
c.close();
|
||||
},
|
||||
});
|
||||
return new Response(body, { status: 200, headers: { "content-type": "text/event-stream" } });
|
||||
};
|
||||
|
||||
const mkChunk = (content, finish = null) => ({
|
||||
id: "x",
|
||||
object: "chat.completion.chunk",
|
||||
created: 1,
|
||||
model: "m",
|
||||
choices: [{ index: 0, delta: content ? { content } : {}, finish_reason: finish }],
|
||||
});
|
||||
|
||||
const baseCtx = {
|
||||
provider: "fakeprovider",
|
||||
model: "m",
|
||||
body: { stream: false },
|
||||
stream: true,
|
||||
translatedBody: null,
|
||||
finalBody: null,
|
||||
requestStartTime: Date.now(),
|
||||
connectionId: "c1",
|
||||
apiKey: null,
|
||||
clientRawRequest: null,
|
||||
onRequestSuccess: null,
|
||||
pxpipe: null,
|
||||
reqTag: "",
|
||||
log: null,
|
||||
trackDone: () => {},
|
||||
appendLog: () => {},
|
||||
reqLogger: null,
|
||||
toolNameMap: null,
|
||||
sourceFormat: "openai",
|
||||
};
|
||||
|
||||
describe("Layer 1 — non-streaming stream error patterns", () => {
|
||||
it("returns a 502 error result when content matches a configured pattern", async () => {
|
||||
const result = await handleForcedSSEToJson({
|
||||
...baseCtx,
|
||||
streamErrorPatterns: { fakeprovider: ["Network connection lost"] },
|
||||
providerResponse: sseResponse([mkChunk("Network connection lost."), mkChunk(null, "stop")]),
|
||||
});
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.status).toBe(502);
|
||||
expect(result.error).toContain("Network connection lost");
|
||||
});
|
||||
|
||||
it("succeeds when content does not match", async () => {
|
||||
const result = await handleForcedSSEToJson({
|
||||
...baseCtx,
|
||||
streamErrorPatterns: { fakeprovider: ["Network connection lost"] },
|
||||
providerResponse: sseResponse([mkChunk("hello world"), mkChunk(null, "stop")]),
|
||||
});
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
|
||||
it("ignores patterns for other providers", async () => {
|
||||
const result = await handleForcedSSEToJson({
|
||||
...baseCtx,
|
||||
streamErrorPatterns: { otherprovider: ["hello"] },
|
||||
providerResponse: sseResponse([mkChunk("hello world"), mkChunk(null, "stop")]),
|
||||
});
|
||||
expect(result.success).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user