Skip to content

Expose the pause reason/exception of a shard stopped on ApplyEventException to external observers #565

Description

@jeremydmiller

Summary

When a projection's error policy does not skip (SkipApplyErrors = false), an ApplyEventException routes to SubscriptionAgent.ReportCriticalFailureAsync (src/JasperFx.Events/Daemon/SubscriptionAgent.cs:136-181), which hard-stops execution and sets Status = AgentStatus.Paused with PausedTime (:159). It also publishes a rich ShardState to the ShardStateTracker carrying Action = ShardAction.Paused, PauseReason = ex.ToString(), and Exception = ex (SubscriptionAgent.cs:160-167; ShardState.cs:45,65,81,86,91).

The problem for an external supervisor (e.g. Wolverine's EventSubscriptionAgent, which wraps a shard as a distributed agent):

  • ISubscriptionAgent exposes only Status (the AgentStatus enum) — no PauseReason / Exception accessor. So the supervisor can see that a shard paused, but not why.
  • ShardStateTracker keeps its current-state map (_states) private; the only public surface is Subscribe(...) / WaitForShardState / WaitForShardCondition (ShardStateTracker.cs:19,89,153-213). There is no synchronous "give me the current state for shard X" snapshot an external poller can call.

Request

Add a synchronous way to read the current pause reason/exception for a shard, one of:

  1. a PauseReason (string?) and/or Exception (Exception?) property on ISubscriptionAgent, populated alongside Status = Paused; or
  2. a bool TryGetCurrentState(ShardName name, out ShardState state) (or ShardState? CurrentState(ShardName)) on ShardStateTracker.

Why it matters (context)

This is the JasperFx.Events dependency for Wolverine WO-8 (surface ApplyEventException-stopped shards to the assignment/observer plane with a reason, so CritterWatch can alert and progress doesn't silently flatline). Wolverine can already observe the Paused status today (EventSubscriptionAgent.Status delegates to the live inner agent), so this issue is specifically about exposing the reason text. Wolverine WO-8 is deliberately deferred to ship as a coordinated pair with whatever accessor lands here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions