Task<Result> or ValueTask<Result> tells the router what to do next. The Result struct in PolyBot.Routing is the single control point for the routing pipeline — a lightweight value type with no heap allocation and a simple boolean outcome.
The Result struct
Result.Continue — pass to the next handler
Return Result.Continue when your handler does something useful but is happy to let a downstream handler also run (logging, analytics, partial preprocessing):
Result.StopRouting — end the chain
Return Result.StopRouting when no other handler should process this update:
Result.Handled() — expressive alias
Result.Handled() is exactly equivalent to Result.StopRouting. Use it when you want to emphasise that the update was fully consumed rather than simply stopped:
Returning Task / ValueTask without Result
A handler that returns plain Task or ValueTask (no type parameter) implicitly stops routing. The router treats the absence of a result value as Result.StopRouting:
Task/ValueTask without Result is useful for handlers that fully consume the update. If you need fall-through behavior, return Task<Result>/ValueTask<Result> and use Result.Continue.Multi-handler routing walkthrough
Consider three handlers registered forMessageHandler, ordered by priority:
1
Router receives a Message update
The generated router enters the
Message case of its dispatch switch.2
Handler A runs (Priority 5)
AuditHandler records the message and returns Result.Continue. The router moves on.3
Handler B runs (Priority 0)
EchoHandler sends the echoed message and returns Result.Continue. The router moves on.4
Handler C runs (Priority -1)
StartHandler checks whether this is a /start command. If the command guard passes, it replies and returns Result.StopRouting. The chain ends — no further MessageHandler methods run.5
Guard fails — fall-through beyond Handler C
If the
/start command guard did not pass, the generator skips the handler body entirely. Because no handler returned StopRouting, routing simply ends naturally with no more handlers to try.Equality and comparison
Result implements IEquatable<Result> and provides == / != operators, so you can compare results in tests or conditional logic: