Result<T>: errors as values
Fusion domain code does not throw for validation. It returns a Result<T>: either a success carrying a value, or a failure carrying a list of EjError. Exceptions are reserved for the genuinely unexpected (a bug, a torn network). A flight number that's blank isn't exceptional; it's an expected invalid input, so it comes back as a failed Result, not a thrown exception.
The building idiom is a fluent guard chain. FailIf(condition, error) starts a builder; you chain more FailIf calls; OrSuccess(...) builds the value only if nothing failed. The important detail: FailIf accumulates. It doesn't stop at the first broken rule; it collects them all, so the caller gets every problem at once instead of fixing them one round-trip at a time.
Try it yourself
Trace an accumulating validation
Prove to yourself that FailIf collects, not short-circuits.
Tick every step to confirm you did it.
Throw or Result
A caller passes a blank flight number to a domain factory. What should the factory do?