





















@@ -748,6 +748,22 @@ describe("GatewayClient close handling", () => {
748748client.stop();
749749});
750750751+it("keeps close callback errors inside websocket dispatch", () => {
752+const onClose = vi.fn(() => {
753+throw new Error("close callback failed");
754+});
755+const client = createClientWithIdentity("dev-4", onClose);
756+757+client.start();
758+expect(() => getLatestWs().emitClose(1008, "unauthorized: signature invalid")).not.toThrow();
759+760+expect(onClose).toHaveBeenCalledWith(1008, "unauthorized: signature invalid");
761+expect(logDebugMock).toHaveBeenCalledWith(
762+"gateway client close handler error: Error: close callback failed",
763+);
764+client.stop();
765+});
766+751767it("keeps a managed reconnect timer after gateway restart closes", async () => {
752768vi.useFakeTimers();
753769try {
@@ -1224,6 +1240,35 @@ describe("GatewayClient connect auth payload", () => {
12241240}
12251241});
122612421243+it("keeps hello callback errors inside connect dispatch", async () => {
1244+const onHelloOk = vi.fn(() => {
1245+throw new Error("hello callback failed");
1246+});
1247+const onConnectError = vi.fn();
1248+const client = new GatewayClient({
1249+url: "ws://127.0.0.1:18789",
1250+deviceIdentity: null,
1251+ onHelloOk,
1252+ onConnectError,
1253+});
1254+1255+try {
1256+const { ws, connect } = startClientAndConnect({ client });
1257+1258+expect(() => emitHelloOk(ws, connect.id)).not.toThrow();
1259+await vi.waitFor(() => {
1260+expect(onHelloOk).toHaveBeenCalledOnce();
1261+});
1262+expect(onConnectError).not.toHaveBeenCalled();
1263+expect(ws.lastClose).toBeNull();
1264+expect(logDebugMock).toHaveBeenCalledWith(
1265+"gateway client hello-ok handler error: Error: hello callback failed",
1266+);
1267+} finally {
1268+client.stop();
1269+}
1270+});
1271+12271272function emitConnectFailure(
12281273ws: MockWebSocket,
12291274connectId: string | undefined,
@@ -1728,6 +1773,37 @@ describe("GatewayClient connect auth payload", () => {
17281773});
17291774});
173017751776+it("keeps reconnect paused callback errors inside close dispatch", async () => {
1777+const onReconnectPaused = vi.fn(() => {
1778+throw new Error("paused callback failed");
1779+});
1780+const onClose = vi.fn();
1781+const client = new GatewayClient({
1782+url: "ws://127.0.0.1:18789",
1783+token: "shared-token",
1784+ onReconnectPaused,
1785+ onClose,
1786+});
1787+1788+const { ws: ws1, connect: firstConnect } = startClientAndConnect({ client });
1789+await expectNoReconnectAfterConnectFailure({
1790+ client,
1791+firstWs: ws1,
1792+connectId: firstConnect.id,
1793+failureDetails: { code: "AUTH_TOKEN_MISSING" },
1794+});
1795+1796+expect(onReconnectPaused).toHaveBeenCalledWith({
1797+code: 1008,
1798+reason: "connect failed",
1799+detailCode: "AUTH_TOKEN_MISSING",
1800+});
1801+expect(logDebugMock).toHaveBeenCalledWith(
1802+"gateway client reconnect paused handler error: Error: paused callback failed",
1803+);
1804+expect(onClose).toHaveBeenCalledWith(1008, "connect failed");
1805+});
1806+17311807it("does not auto-reconnect on CLIENT_VERSION_MISMATCH connect failures", async () => {
17321808const onReconnectPaused = vi.fn();
17331809const client = new GatewayClient({
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。