diff --git a/app/src/main/java/com/m57/hermescontrol/data/ws/HermesWsClient.kt b/app/src/main/java/com/m57/hermescontrol/data/ws/HermesWsClient.kt index ab3fa379..1098e7be 100644 --- a/app/src/main/java/com/m57/hermescontrol/data/ws/HermesWsClient.kt +++ b/app/src/main/java/com/m57/hermescontrol/data/ws/HermesWsClient.kt @@ -775,6 +775,7 @@ object HermesWsClient { val method: String, val deferred: CompletableDeferred, var timeoutJob: Job? = null, + val suppressErrorEvent: Boolean = false, ) /** Tracks in-flight [request] calls by their JSON-RPC id. */ @@ -794,11 +795,12 @@ object HermesWsClient { method: String, params: Map = emptyMap(), timeoutMs: Long = REQUEST_TIMEOUT_MS, + suppressErrorEvent: Boolean = false, ): CompletableDeferred { val deferred = CompletableDeferred() val id = send(method, params) { reqId -> - pendingCalls[reqId] = PendingCall(method, deferred) + pendingCalls[reqId] = PendingCall(method, deferred, suppressErrorEvent = suppressErrorEvent) } deferred.invokeOnCompletion { cause -> if (cause is CancellationException) { @@ -1458,6 +1460,16 @@ object HermesWsClient { disconnectIfIdleInBackground() } } + if (pendingCalls[event.id]?.suppressErrorEvent == true) { + // Opt-in suppression: the caller already handles the + // failure through the CompletableDeferred, so the event + // copy would only surface a duplicate UI banner for + // optional features (e.g. "subagent.list" on gateways + // without the method, issue #1089). Default request() + // behavior still emits the event for shared consumers. + resolvePending(event.id, null, event.error) + return + } removeQueuedMessage(event.id) resolvePending(event.id, null, event.error) } diff --git a/app/src/main/java/com/m57/hermescontrol/data/ws/SubagentRepository.kt b/app/src/main/java/com/m57/hermescontrol/data/ws/SubagentRepository.kt index 45a9ac37..1cda13ec 100644 --- a/app/src/main/java/com/m57/hermescontrol/data/ws/SubagentRepository.kt +++ b/app/src/main/java/com/m57/hermescontrol/data/ws/SubagentRepository.kt @@ -37,6 +37,7 @@ object SubagentRepository { .request( WsMethods.SUBAGENT_LIST, mapOf("session_id" to sessionId), + suppressErrorEvent = true, ).await() decode(result) } catch (e: Exception) { @@ -65,7 +66,13 @@ object SubagentRepository { if (sessionId.isNotBlank()) { params["session_id"] = sessionId } - val result = HermesWsClient.request(WsMethods.SUBAGENT_TAIL, params).await() + val result = + HermesWsClient + .request( + WsMethods.SUBAGENT_TAIL, + params, + suppressErrorEvent = true, + ).await() return decode(result) }