Skip to content

fix(remote-connect): surface relay rejection reason for peer events - #3655

Merged
bobleer merged 1 commit into
GCWing:mainfrom
gordon-gs:fix/relay-event-rejection-reason
Nov 2, 2026
Merged

bobleer merged 1 commit into
GCWing:mainfrom
gordon-gs:fix/relay-event-rejection-reason

Conversation

@gordon-gs

Copy link
Copy Markdown
Contributor

问题

RealtimeSender::event 在 relay 返回 {"ok": false, ...} 时,直接 bail!("Relay event rejected"),把 ack 里的 error 丢掉了。

结果是:任何一次 peer event fanout 失败,日志都长得一模一样:

[DEBUG][openbitfun_desktop_lib::api::remote_connect_api] peer event fanout to <peer> failed: Relay event rejected

但 relay 侧其实是有区分度的 —— src/crates/services/relay-service/src/realtime/mod.rs 的 machine-event handler 会返回:

  • event forbidden
  • event target offline
  • invalid event
  • 或 {"ok": false}(目标 socket emit 失败)

这几种情况在排查时是完全不同的方向,现在一条都看不到。

证据

本机 app.log 里这条日志连续刷了 483 条(15:49:43 → 16:42:05),涉及两个不同的 peer,全都是同一句 Relay event rejected。期间 RPC 通道是正常的(每 2 秒一条 RPC request received from relay),说明不是连接整体断开。

产生的实际影响:无法判断到底是 controller 已经离线(event target offline,host 侧 controller 列表是陈旧的),还是事件被 relay 拒绝,只能靠猜。

改动

RealtimeSender::event 保留 relay 的拒绝原因,与同文件里 RealtimeSender::call 已有的写法保持一致(那里已经是 bail!("{}", result["error"]...)):

if response.payload.0["ok"] != true {
    bail!(
        "Relay event rejected: {}",
        response.payload.0["error"]
            .as_str()
            .unwrap_or("no reason provided by relay")
    );
}

改完之后日志会变成:

peer event fanout to <peer> failed: Relay event rejected: event target offline

关联现象(不在本 PR 范围)

Remote Web 端(remote.openbitfun.com)聊天页的 prompt suggestion 气泡一直不出现。四端(web / iOS / Android / HarmonyOS)的 UI 实现都是有的:

  • src/mobile-web/src/components/ChatComposerBar.tsx(visibleSuggestion)
  • src/apps/mobile/ios/OpenBitFun/Features/Chat/ComposerBar.swift + PromptSuggestionUITests.swift
  • src/apps/mobile/android/app/src/main/kotlin/com/openbitfun/mobile/app/ui/chat/ComposerBar.kt

session_event_publication 也已经把 agentic://prompt-suggestion 标成「到达 controller 但不写 transcript」(persist_control: true),并有测试覆盖。所以问题大概率不在 UI,而在 peer event 推送这一段 —— 也正是本 PR 想让它变得可观测的那条路径。

不声称本 PR 修复了那个问题;它只是让下一次失败能直接说明原因。

验证

cargo check -p openbitfun-services-integrations

通过。

`RealtimeSender::event` discarded the relay acknowledgement payload and
returned a fixed "Relay event rejected" error, so every failed peer event
fanout produced the same undiagnosable log line. The relay returns
`{"ok": false, "error": "..."}` (for example `event target offline`),
which is exactly the information needed to tell an offline controller
apart from a forbidden or malformed event.

`RealtimeSender::call` already surfaces `payload["error"]`; make `event`
consistent with it.
@GCWing
GCWing requested a review from bobleer November 2, 2026 01:46
@bobleer
bobleer merged commit 311417a into GCWing:main Nov 2, 2026
13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants