{"record":{"id":"8eac6296f15fcc5e","repo":"mgth/LittleBigMouse","slug":"the-vidaa-connection-is-not-open-vidaasession","errorCode":null,"errorMessage":"The VIDAA connection is not open.","messagePattern":"The VIDAA connection is not open\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaSession.cs","lineNumber":111,"sourceCode":"        connection.MessageReceived -= Dispatch;\n        await connection.DisposeAsync().ConfigureAwait(false);\n    }\n\n    /// <summary>\n    /// Tells a session the broker dropped from a command the device refused, so that only the\n    /// former is worth sending again.\n    /// </summary>\n    public static bool IsConnectionFailure(Exception exception)\n        => exception is IOException or SocketException or ObjectDisposedException;\n\n    async Task ReopenAsync(CancellationToken cancellationToken)\n    {\n        await CloseAsync().ConfigureAwait(false);\n        await EnsureOpenAsync(cancellationToken).ConfigureAwait(false);\n    }\n\n    IVidaaConnection Open()\n        => _connection ?? throw new InvalidOperationException(\"The VIDAA connection is not open.\");\n\n    void Dispatch(string topic, byte[] payload, bool retained)\n        => MessageReceived?.Invoke(topic, payload, retained);\n}\n","sourceCodeStart":93,"sourceCodeEnd":116,"githubUrl":"https://github.com/mgth/LittleBigMouse/blob/7a42f01d47d99d223b8ee33ba4019af82adf1c48/LittleBigMouse.Plugins/LittleBigMouse.Plugin.Vcp.Avalonia/HisenseVidaa/VidaaSession.cs#L93-L116","documentation":"The private Open() accessor returns the current connection object but throws InvalidOperationException if _connection is null, i.e. the session is not currently open. PublishAsync/SubscribeAsync/UnsubscribeAsync rely on it to guarantee they never operate on a closed connection.","triggerScenarios":"Calling PublishAsync, SubscribeAsync or UnsubscribeAsync on a VidaaSession before EnsureOpenAsync succeeded, or after CloseAsync/the connection dropped (device offline, socket closed, exception in the message loop).","commonSituations":"Fire-and-forget publish after a network blip killed the connection; subscribing to response topics before opening; a background worker keeps publishing while the UI closed the session; race between reconnect and publish.","solutions":["Call EnsureOpenAsync(ct) (or await ReopenAsync) before any publish/subscribe call","Check the Connected property before publishing and reopen when false","Wrap publishes in try/catch on InvalidOperationException and reopen+retry once","Investigate why the connection dropped (device standby, network) if it recurs"],"exampleFix":"// before\nsession.PublishAsync(topic, payload, ct); // may throw if closed\n// after\nawait session.EnsureOpenAsync(ct);\nawait session.PublishAsync(topic, payload, ct);","handlingStrategy":"retry","validationCode":"if (!session.Connected)\n    await session.EnsureOpenAsync(ct);\nawait session.PublishAsync(topic, payload, ct);","typeGuard":"bool CanPublish(IVidaaSession session) => session.Connected;","tryCatchPattern":"try\n{\n    await session.PublishAsync(topic, payload, ct);\n}\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"VIDAA connection is not open\"))\n{\n    await session.ReopenAsync(ct);\n    await session.PublishAsync(topic, payload, ct);\n}","preventionTips":["Serialize publishes through a single method that opens the session on demand","Subscribe to MessageReceived/connection-lost events to reopen proactively","Avoid publishing while the device may be in standby; wake/check first","Guard against concurrent publish/reconnect races with a semaphore"],"tags":["csharp","mqtt","connection-state","invalid-operation"],"backgroundTag":"connection-refused","analyzedSha":"7a42f01d47d99d223b8ee33ba4019af82adf1c48","analyzedAt":"2026-09-16T00:35:00.514Z","contentChangedAt":"2026-09-16T00:35:00.514Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}