From 827e35070dfb1411b87cbdb93b0abeab3b530da2 Mon Sep 17 00:00:00 2001 From: Bas van den Wollenberg Date: Thu, 26 Feb 2026 16:11:52 +0100 Subject: [PATCH] show websocket close event --- src/utils/websocket.ts | 20 ++++++++++++++++++++ src/views/stream/index.tsx | 13 +++++++++++++ 2 files changed, 33 insertions(+) create mode 100644 src/utils/websocket.ts diff --git a/src/utils/websocket.ts b/src/utils/websocket.ts new file mode 100644 index 0000000..faac2db --- /dev/null +++ b/src/utils/websocket.ts @@ -0,0 +1,20 @@ +const _websocketCloseReasons = { + 1000: "Normal Closure", + 1001: "Going Away", + 1002: "Protocol Error", + 1003: "Unsupported Data", + 1005: "No Status Received", + 1006: "Abnormal Closure", + 1007: "Invalid frame payload data", + 1008: "Policy Violation", + 1009: "Message too big", + 1010: "Missing Extension", + 1011: "Internal Error", + 1012: "Service Restart", + 1013: "Try Again Later", + 1014: "Bad Gateway", + 1015: "TLS Handshake", +} as const; + +export const websocketCloseReasons = _websocketCloseReasons as typeof _websocketCloseReasons & + Record; diff --git a/src/views/stream/index.tsx b/src/views/stream/index.tsx index dcca962..32ccc9e 100644 --- a/src/views/stream/index.tsx +++ b/src/views/stream/index.tsx @@ -7,6 +7,7 @@ import DidHoverCard from "../../components/hover-card/did"; import { JSONValue } from "../../components/json"; import { TextInput } from "../../components/text-input"; import { addToClipboard } from "../../utils/copy"; +import { websocketCloseReasons } from "../../utils/websocket"; import { getStreamType, STREAM_CONFIGS, STREAM_TYPES, StreamType } from "./config"; import { StreamStats, StreamStatsPanel } from "./stats"; @@ -183,6 +184,14 @@ export const StreamView = () => { setStats((prev) => ({ ...prev, eventsPerSecond: 0 })); }; + const onWebsocketClose = (event: CloseEvent) => { + const code = event.code.toString(); + if (code === "1000" || code === "1005") return; + + setNotice(`Connection closed: ${websocketCloseReasons[code] ?? "Unknown reason"}`); + disconnect(); + }; + const connectStream = async (formData: FormData) => { setNotice(""); if (connected()) { @@ -251,7 +260,9 @@ export const StreamView = () => { if (!isFilteredEvent || streamType !== "jetstream" || searchParams.allEvents === "on") addRecord(rec); }); + socket.addEventListener("close", onWebsocketClose); socket.addEventListener("error", () => { + socket.removeEventListener("close", onWebsocketClose); setNotice("Connection error"); disconnect(); }); @@ -262,7 +273,9 @@ export const StreamView = () => { cursor: cursor, autoReconnect: false, }); + firehose.ws.addEventListener("close", onWebsocketClose); firehose.on("error", (err) => { + firehose.ws.removeEventListener("close", onWebsocketClose); console.error(err); const message = err instanceof Error ? err.message : "Unknown error"; setNotice(`Connection error: ${message}`); -- 2.51.2