From 901bb767b56250915de2b866db91e4e2d8b098b0 Mon Sep 17 00:00:00 2001 From: Gustavo Madeira Santana Date: Wed, 8 Apr 2026 13:58:19 -0400 Subject: [PATCH] fix(matrix): ignore shutdown sync-state noise --- .../src/matrix/monitor/sync-lifecycle.test.ts | 30 +++++++++++++++++++ .../src/matrix/monitor/sync-lifecycle.ts | 6 ++++ 2 files changed, 36 insertions(+) diff --git a/extensions/matrix/src/matrix/monitor/sync-lifecycle.test.ts b/extensions/matrix/src/matrix/monitor/sync-lifecycle.test.ts index 463f5361199..76818528374 100644 --- a/extensions/matrix/src/matrix/monitor/sync-lifecycle.test.ts +++ b/extensions/matrix/src/matrix/monitor/sync-lifecycle.test.ts @@ -114,6 +114,36 @@ describe("createMatrixMonitorSyncLifecycle", () => { ); }); + it("ignores non-terminal sync states emitted during intentional shutdown", async () => { + const client = createClientEmitter(); + const setStatus = vi.fn(); + let stopping = false; + const statusController = createMatrixMonitorStatusController({ + accountId: "default", + statusSink: setStatus, + }); + const lifecycle = createMatrixMonitorSyncLifecycle({ + client: client as never, + statusController, + isStopping: () => stopping, + }); + + const waitPromise = lifecycle.waitForFatalStop(); + stopping = true; + client.emit("sync.state", "ERROR", "RECONNECTING", new Error("shutdown noise")); + lifecycle.dispose(); + statusController.markStopped(); + + await expect(waitPromise).resolves.toBeUndefined(); + expect(setStatus).toHaveBeenLastCalledWith( + expect.objectContaining({ + accountId: "default", + healthState: "stopped", + lastError: null, + }), + ); + }); + it("does not downgrade a fatal error to stopped during shutdown", async () => { const client = createClientEmitter(); const setStatus = vi.fn(); diff --git a/extensions/matrix/src/matrix/monitor/sync-lifecycle.ts b/extensions/matrix/src/matrix/monitor/sync-lifecycle.ts index ae07c09a575..db58300fe33 100644 --- a/extensions/matrix/src/matrix/monitor/sync-lifecycle.ts +++ b/extensions/matrix/src/matrix/monitor/sync-lifecycle.ts @@ -47,6 +47,12 @@ export function createMatrixMonitorSyncLifecycle(params: { if (fatalError) { return; } + // Operator-initiated shutdown can still emit transient sync states before + // the final STOPPED. Ignore that churn so intentional stops do not look + // like runtime failures. + if (params.isStopping?.() && !isMatrixTerminalSyncState(state)) { + return; + } params.statusController.noteSyncState(state, error); };