Skip to content

fix(flow-service,udp-notif-service): surface actor setup failure on early exit - #53

Draft
rodonile wants to merge 1 commit into
network-analytics:mainfrom
rodonile:actor-binderr-vis
Draft

fix(flow-service,udp-notif-service): surface actor setup failure on early exit#53
rodonile wants to merge 1 commit into
network-analytics:mainfrom
rodonile:actor-binderr-vis

Conversation

@rodonile

@rodonile rodonile commented Sep 7, 2026

Copy link
Copy Markdown
Member

Summary

FlowCollectorActorHandle::new and ActorHandle::new now race the
actor's JoinHandle against the LocalAddr reply channel instead of
only awaiting the reply. This surfaces the actor's real error (e.g. a
socket bind failure) when it exits before responding, rather than a
generic ReceiveError.

Reason

If actor startup failed (e.g. bind() error), the reply sender was
dropped without sending a response, and callers only ever saw
ReceiveError, hiding the actual cause and making failures harder to
diagnose.

Changes

  • Added ActorFailed(FlowCollectorActorError) /
    ActorFailed(UdpNotifActorError) variants to the respective handle
    error enums.
  • new() now uses tokio::select! (biased toward the join handle) to
    detect early actor termination and propagate its error.

Previously, if the actor task exited (e.g. due to a socket bind
error) before replying with its local address, the handle's new()
would return a generic ReceiveError, discarding the actual cause.

Race the reply channel against the actor's JoinHandle so that when
the actor dies first, its real error is propagated via the new
ActorFailed variant instead of being masked.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new early-failure surfacing still leaves a race where send(LocalAddr) failures return generic SendError (and the new ActorFailed variants aren’t exposed via the error chain), which can continue to hide the real startup cause.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

This PR improves startup error reporting for flow-service and udp-notif-service actor handles by detecting when an actor task terminates before it can return its LocalAddr, and by propagating the actor’s real failure (e.g., socket bind errors) instead of a generic channel receive error.

Changes:

  • Added ActorFailed(...) variants to the handle error enums to carry the actor’s startup failure.
  • Updated *_Handle::new() to tokio::select! between the actor JoinHandle and the LocalAddr reply to detect early termination and surface the underlying error.
File summaries
File Description
crates/udp-notif-service/src/actor.rs Adds ActorFailed(UdpNotifActorError) and races join-handle vs. local-addr response during handle creation.
crates/flow-service/src/flow_actor.rs Adds ActorFailed(FlowCollectorActorError) and applies the same early-exit detection during handle creation.
Review details

Suppressed comments (2)

crates/udp-notif-service/src/actor.rs:1045

  • If the actor exits very quickly (e.g. bind() fails), cmd_tx.send(LocalAddr) can also fail with the receiver already dropped, and this path still returns SendError which hides the real cause. Since this PR is about surfacing early actor startup failures, consider awaiting the join handle on send failure and returning ActorFailed when available.
        cmd_tx
            .send(ActorCommand::LocalAddr(tx))
            .await
            .map_err(|_| ActorHandleError::SendError)?;

crates/flow-service/src/flow_actor.rs:967

  • As with the udp-notif actor, if the actor task fails immediately (e.g. socket bind failure), cmd_tx.send(LocalAddr) can race and fail with the receiver already dropped. Returning SendError here still hides the actor's real startup error; awaiting the join handle on send failure would better match the PR goal of surfacing early-exit failures.
        cmd_tx
            .send(FlowCollectorActorCommand::LocalAddr(tx))
            .await
            .map_err(|_| FlowCollectorActorHandleError::SendError)?;
  • Files reviewed: 2/2 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines 899 to 907
impl std::error::Error for FlowCollectorActorHandleError {
fn description(&self) -> &str {
match *self {
FlowCollectorActorHandleError::SendError => "Error sending command to actor",
FlowCollectorActorHandleError::ReceiveError => "Error receiving response from actor",
FlowCollectorActorHandleError::ActorFailed(_) => {
"actor terminated before it could start"
}
}
Comment on lines 981 to 985
match *self {
ActorHandleError::SendError => "error sending command to actor",
ActorHandleError::ReceiveError => "error receiving response from actor",
ActorHandleError::ActorFailed(_) => "actor terminated before it could start",
}
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