feat(open-sse): streamErrorPatterns matching util (text + regex)
This commit is contained in:
47
open-sse/utils/streamErrorPatterns.js
Normal file
47
open-sse/utils/streamErrorPatterns.js
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Config-driven in-stream error pattern matching.
|
||||
* See docs/2026-08-04-stream-error-patterns-design.md.
|
||||
*
|
||||
* Settings shape: streamErrorPatterns: { [provider]: string[] }
|
||||
* Pattern syntax per entry:
|
||||
* - "plain text" → case-insensitive substring match
|
||||
* - "/regex/flags" → RegExp match (flags after the last "/")
|
||||
*/
|
||||
|
||||
export function parsePatterns(patterns) {
|
||||
if (!Array.isArray(patterns)) return [];
|
||||
const out = [];
|
||||
for (const entry of patterns) {
|
||||
if (typeof entry !== "string" || !entry.trim()) continue;
|
||||
const raw = entry.trim();
|
||||
const m = raw.match(/^\/(.*)\/([a-z]*)$/s);
|
||||
if (m) {
|
||||
try {
|
||||
out.push({ regex: new RegExp(m[1], m[2]), raw });
|
||||
} catch {
|
||||
// invalid regex → skip; config errors must never break requests
|
||||
}
|
||||
continue;
|
||||
}
|
||||
out.push({ text: raw.toLowerCase(), raw });
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
export function matchStreamErrorPatterns(patterns, text) {
|
||||
if (!Array.isArray(patterns) || patterns.length === 0) return null;
|
||||
if (typeof text !== "string" || !text) return null;
|
||||
const lower = text.toLowerCase();
|
||||
for (const p of parsePatterns(patterns)) {
|
||||
if (p.text && lower.includes(p.text)) return p.raw;
|
||||
if (p.regex) {
|
||||
p.regex.lastIndex = 0; // stateless even with /g
|
||||
if (p.regex.test(text)) return p.raw;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function streamStatusForContent(patterns, content) {
|
||||
return matchStreamErrorPatterns(patterns, content) ? "error" : "success";
|
||||
}
|
||||
Reference in New Issue
Block a user