fix(ui): отклонять повреждённые данные live-потока

This commit is contained in:
Denozordec committed 2026-09-24 09:58:32 +07:00
1 parent 094c812c37
commit a03909e504
3 files changed
+40 -11

No files matched your search

+8 -9
View File
@@ -1,7 +1,7 @@
"use client"
import { useEffect, useState } from "react"
import type { FlowAnalyticsDto } from "@mmapp/contracts/traffic-flow"
import { flowAnalyticsDtoSchema, type FlowAnalyticsDto } from "@mmapp/contracts/traffic-flow"
import { resolveApiUrl, withAuthHeaders } from "@/shared/api/http-client"
import { flowQuery } from "@/shared/api/traffic-flow"
@@ -16,9 +16,8 @@ function parseSseBlock(block: string): { event: string; data: string } {
}
export function isValidFlowLiveSample(value: unknown): value is FlowAnalyticsDto {
if (!value || typeof value !== "object") return false
const v = value as Partial<FlowAnalyticsDto>
return typeof v.uniqueSrc === "number" && Array.isArray(v.destinations)
const parsed = flowAnalyticsDtoSchema.safeParse(value)
return parsed.success && [...parsed.data.rxSeries, ...parsed.data.txSeries].every(value => Number.isFinite(value) && value >= 0)
}
export function useFlowLive(opts: {
@@ -81,19 +80,19 @@ export function useFlowLive(opts: {
if (ev.event === "sample" && ev.data) {
const parsed = JSON.parse(ev.data) as unknown
if (!isValidFlowLiveSample(parsed)) {
setError("live sample пустой")
continue
throw new Error("Некорректные данные live-потока")
}
setResult({ key, sample: parsed, error: parsed.degraded ? "Коллектор перегружен: упрощённая аналитика" : null })
} else if (ev.event === "error" && ev.data) {
const parsed = JSON.parse(ev.data) as { error?: string }
setError(parsed.error ?? "live error")
const parsed: unknown = JSON.parse(ev.data)
throw new Error(parsed && typeof parsed === "object" && "error" in parsed && typeof parsed.error === "string" ? parsed.error : "Ошибка live-потока")
}
}
}
} catch (e) {
if (ac.signal.aborted) return
setError(e instanceof Error ? e.message : "live error")
setError(e instanceof Error ? e.message : "Ошибка live-потока")
ac.abort()
}
})()