Files
OmniRoute/open-sse/utils/streamFailureFinalization.ts
Diego Rodrigues de Sa e Souza 81a37b67ed Release v3.8.26 (#3875)
OmniRoute v3.8.26 — see CHANGELOG.md [3.8.26] for the full notes.

Highlights: Vertex AI media generation (#3929), GLM-5.2 effort-tier routing (#3885),
sticky round-robin combos (#3846), OpenRouter connection presets (#3878), compression
prompt-cache fix (#3936/#3890), and a security pass (form-data/vite + workflow hardening, #3949).

Co-authored-by: artickc <artickc@users.noreply.github.com>
Co-authored-by: rdself <rdself@users.noreply.github.com>
Co-authored-by: herjarsa <herjarsa@users.noreply.github.com>
Co-authored-by: Jack Smith <16862258+YunyunZhai@users.noreply.github.com>
Co-authored-by: dhaern <dhaern@users.noreply.github.com>
Co-authored-by: adivekar-utexas <adivekar-utexas@users.noreply.github.com>
Co-authored-by: megamen32 <megamen32@users.noreply.github.com>
Co-authored-by: zhiru <zhiru@users.noreply.github.com>
Co-authored-by: insoln <insoln@users.noreply.github.com>
Co-authored-by: diego-anselmo <diego-anselmo@users.noreply.github.com>
2026-06-16 01:00:40 -03:00

152 lines
3.8 KiB
TypeScript

import {
finalizeMostRecentPendingRequest,
finalizePendingRequestById,
} from "@/lib/usage/usageHistory.ts";
import { HTTP_STATUS } from "../config/constants.ts";
import { buildErrorBody } from "./error.ts";
export type StreamCompletionPayload = {
status: number;
usage: unknown;
responseBody?: unknown;
providerPayload?: unknown;
clientPayload?: unknown;
error?: string | null;
errorCode?: string | null;
ttft?: number | null;
};
export type StreamFailurePayload = {
status: number;
message: string;
code?: string;
type?: string;
};
export type PipelineStreamErrorHandler = (event: {
message: string;
statusCode: number;
}) => boolean;
export function finalizeStreamRequestLog({
pendingRequestId,
model,
provider,
connectionId,
providerResponse,
clientResponse,
status,
error,
errorCode,
onWarn,
}: {
pendingRequestId: string;
model: string;
provider: string;
connectionId: string | null;
providerResponse?: unknown;
clientResponse?: unknown;
status: number;
error?: string | null;
errorCode?: string | null;
onWarn?: (error: unknown) => void;
}) {
try {
const completedById = finalizePendingRequestById(pendingRequestId, {
providerResponse,
clientResponse,
status,
error: error || null,
errorCode: errorCode || null,
});
if (!completedById) {
finalizeMostRecentPendingRequest(model, provider, connectionId, {
providerResponse,
clientResponse,
status,
error: error || null,
errorCode: errorCode || null,
});
}
} catch (error) {
try {
if (onWarn) {
onWarn(error);
} else {
console.warn(
"finalizeMostRecentPendingRequest failed:",
error && typeof error === "object" && "message" in error
? (error as { message?: unknown }).message
: error
);
}
} catch {}
}
}
export function createStreamFailureFinalizers({
isFailureCompletionRecorded,
onStreamComplete,
persistFailureUsage,
onStreamFailure,
}: {
isFailureCompletionRecorded: () => boolean;
onStreamComplete: (payload: StreamCompletionPayload) => void;
persistFailureUsage: (status: number, errorCode?: string) => void;
onStreamFailure?: ((failure: StreamFailurePayload) => void) | null;
}) {
const handleStreamFailure = (failure: StreamFailurePayload) => {
const status = failure.status || HTTP_STATUS.BAD_GATEWAY;
const message = failure.message || "Upstream stream error";
const code = failure.code || failure.type || String(status);
if (!isFailureCompletionRecorded()) {
const errorBody = buildErrorBody(status, message);
onStreamComplete({
status,
usage: null,
responseBody: errorBody,
providerPayload: errorBody,
clientPayload: errorBody,
error: message,
errorCode: code,
ttft: 0,
});
}
persistFailureUsage(status, code);
try {
onStreamFailure?.(failure);
} catch {
// Best-effort fallback state update only.
}
return true;
};
let pipelineStreamFailureFinalized = false;
const onPipelineStreamError: PipelineStreamErrorHandler = ({ message, statusCode }) => {
if (pipelineStreamFailureFinalized) return true;
pipelineStreamFailureFinalized = true;
const status =
Number.isFinite(statusCode) && statusCode >= 400 && statusCode <= 599
? statusCode
: HTTP_STATUS.BAD_GATEWAY;
const normalizedMessage = message || "Upstream stream error";
const code = normalizedMessage.toLowerCase().includes("terminated")
? "stream_terminated"
: "stream_pipeline_error";
handleStreamFailure({
status,
message: normalizedMessage,
code,
type: "stream_error",
});
return true;
};
return { handleStreamFailure, onPipelineStreamError };
}