mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-07-26 09:52:11 +03:00
* fix(combo,model-fallback,sqljs): three stream-reliability fixes - targetExhaustion: skip remaining same-provider models on 401 auth failure (prevents opencode-zen noauth cascade wasting retry attempts) (#8133) - modelFamilyFallback: skip unsupported models in T5 fallback chain (prevents GitHub provider trying deprecated claude-opus-4.8/4.7) (#8134) - sqljsAdapter: split package.json resolve string to suppress Next.js Can't resolve warning at build time (#8135) * fix(stream): add logging to empty catch blocks in stream error handling - stream.ts: Log errors in onComplete/onFailure callbacks (lines 929, 1112, 2451, 2536, 2561, 2717) - streamHandler.ts: Log errors in stall watchdog and trackPendingRequest (lines 249, 334, 657, 663, 667) - cursor.ts: Add comments to intentional H2 lifecycle catches, log KV/exec errors - next.config.mjs: Externalize sql.js to suppress build warnings Closes #8138, #8139, #8140, #8141, #8142 * refactor(stream): scope PR to logging hygiene, drop out-of-scope exhaustion/fallback hunks Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> * chore(quality): rebaseline stream.ts for #8143 empty-catch logging own-growth Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> --------- Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com> Co-authored-by: rafaumeu <rafael.zendron22@gmail.com> Co-authored-by: chirag127 <chirag127@users.noreply.github.com>
70 lines
2.0 KiB
TypeScript
70 lines
2.0 KiB
TypeScript
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
|
|
import { pipeWithDisconnect } from "../../open-sse/utils/streamHandler.ts";
|
|
|
|
const encoder = new TextEncoder();
|
|
const decoder = new TextDecoder();
|
|
|
|
async function readStreamText(stream) {
|
|
const reader = stream.getReader();
|
|
const chunks = [];
|
|
|
|
while (true) {
|
|
const { done, value } = await reader.read();
|
|
if (done) break;
|
|
chunks.push(value);
|
|
}
|
|
|
|
return decoder.decode(
|
|
chunks.length === 1 ? chunks[0] : Uint8Array.from(chunks.flatMap((chunk) => Array.from(chunk)))
|
|
);
|
|
}
|
|
|
|
// Regression guard for #8143's logging-hygiene fix: the stall watchdog's
|
|
// `streamController.handleError?.()` call used to be wrapped in a bare
|
|
// `catch {}` that silently swallowed any exception raised by the callback.
|
|
// It must now log via console.debug so the failure is observable instead of
|
|
// vanishing without a trace.
|
|
test("pipeWithDisconnect stall watchdog logs instead of silently swallowing a throwing handleError", async () => {
|
|
const source = new ReadableStream({
|
|
start(controller) {
|
|
controller.enqueue(encoder.encode("x"));
|
|
// never enqueue again, never close — forces the stall watchdog to fire
|
|
},
|
|
cancel() {},
|
|
});
|
|
|
|
const streamController = {
|
|
isConnected: () => true,
|
|
handleError() {
|
|
throw new Error("handleError callback exploded");
|
|
},
|
|
handleComplete() {},
|
|
abort() {},
|
|
};
|
|
|
|
const debugCalls = [];
|
|
const originalDebug = console.debug;
|
|
console.debug = (...args) => {
|
|
debugCalls.push(args);
|
|
};
|
|
|
|
try {
|
|
const stream = pipeWithDisconnect(new Response(source), new TransformStream(), streamController, {
|
|
stallTimeoutMs: 40,
|
|
});
|
|
await readStreamText(stream);
|
|
} finally {
|
|
console.debug = originalDebug;
|
|
}
|
|
|
|
const loggedStallFailure = debugCalls.some((args) =>
|
|
String(args[0]).includes("stall watchdog handleError failed")
|
|
);
|
|
assert.ok(
|
|
loggedStallFailure,
|
|
"a throwing handleError during the stall watchdog must be logged via console.debug, not swallowed"
|
|
);
|
|
});
|