Repository navigation
Bind every server push in the desktop app - #1052
Conversation
SignalR binds a push with no handler against no parameters, so each one carrying an argument threw and was caught on the receive loop. A push's arity is frozen like a hub method's: an added argument fails to bind in installed apps. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
PR Summary by QodoBind every SignalR server push in the desktop app
AI Description
Diagram
High-Level Assessment
Files changed (5)
|
Code Review by Qodo
1.
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 57c0fd3247
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| HubBroadcasts.SessionTitleChanged, HubBroadcasts.ActiveSessionAdded, HubBroadcasts.ActiveSessionChanged, | ||
| HubBroadcasts.ActiveSessionRemoved, HubBroadcasts.SessionDeleted, HubBroadcasts.SessionEvalCompleted, |
There was a problem hiding this comment.
Bind ActiveSession payloads as JSON
When ActiveSessionAdded, ActiveSessionChanged, or ActiveSessionRemoved carries an object-shaped session payload, these string handlers still produce the ArgumentBindingFailure this change is intended to eliminate. The existing compatibility sinks for the same /hubs/sessions connection deliberately bind these broadcasts as JsonElement in src/Capacitor.Cli.Daemon/Services/ServerConnection.cs:386-388, while the new test only broadcasts fabricated string values, so it cannot catch this failure; use a payload type that accepts the actual JSON shape.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Both server paths that send these, UiBroadcast and PublicHubTransport, pass the session id as a string, so they bind today, and the test's samples are those wire shapes. For a no-op handler, taking the argument as a JsonElement costs nothing and leaves the argument count as the only thing that has to match, so every unused push with an argument now binds that way (e630188).
| public const string FlowsChanged = "FlowsChanged"; | ||
| public const string WorkItemsChanged = "WorkItemsChanged"; | ||
| public const string ProjectsChanged = "ProjectsChanged"; |
There was a problem hiding this comment.
Include the WelcomeStateChanged broadcast
Add WelcomeStateChanged to this registry and register its zero-argument no-op handler. The daemon's RegisterUiBroadcastSinks identifies it as a UI-only broadcast sent on the same /hubs/sessions connection (src/Capacitor.Cli.Daemon/Services/ServerConnection.cs:363-384), but it is absent here, so desktop clients still log MissingHandler whenever the server emits it. The reflection test cannot detect the omission because it derives its expected set from this incomplete class.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Confirmed: PublicHubTransport sends it with no argument to audience groups the app joins. Added to HubBroadcasts and the unused no-argument pushes; the test failed with MissingHandler:WelcomeStateChanged before the registration (e630188). Catching a server push that is missing from HubBroadcasts needs a guard in kcap-server, which is tracked as a follow-up.
The server's audience transport sends it with no argument. An unused push's argument binds as JsonElement, so only the count has to match the server's. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
155c73e to
e630188
Compare
Closes #1046 — AI-2994
What & why
The app's hub connection sits in the server's UI-clients group, and every push there that carries an argument but has no handler threw an
InvalidDataExceptionthat the SignalR client caught and dropped. The app now registers a no-op handler for each push it does not use, with the same number of arguments as the server sends (each taken as aJsonElement), andHubBroadcastsnames every push a UI client can receive, includingRawStreamAccessRevokedandWelcomeStateChangedfrom the server's audience transport. Leaving the app out of the group would cut off the permission, launch-failure and agent/daemon pushes it does consume.Where to look
ArgumentBindingFailureat Error, not Debug.HubBroadcastsdoes not list remains a follow-up.Verification
EveryServerPushBindsToAHandlersends everyHubBroadcastspush to the test hub and records the client's missing-handler and binding-failure logs. Without the no-op registrations it records a failure for every unused push (ArgumentBindingFailure:ActiveSessionAdded,MissingHandler:WelcomeStateChanged, …) on top of the 3 from its two deliberate unknown pushes; with them, exactly those 3.ServerConnectionServiceTests: 30/30. App suite: 2563/2564;Size_label_and_image_flagfails locally on a decimal comma (nb locale) and passes underen_US.UTF-8.dotnet build Capacitor.slnx --no-incremental: 0 warnings.🤖 Generated with Claude Code