Skip to main content
Every handler that returns 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

There are three ways to express an outcome:

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 for MessageHandler, 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: