Advanced Error Handling — Discriminated Union + Result<T, E> Pattern
Advanced Error Handling — Discriminated Union + Result Pattern
💡 Why Should You Learn This? — Treating Errors as 'Values' Is Safer
Discriminated Union · Result · Exhaustive Check
1. Discriminated Union — Types Narrowed by a Tag Field
Narrowing the tag (kind) field value narrows the entire shape of the object.
2. Result Pattern
If the caller forgets to handle an error, the compiler blocks compilation — accessing r.value directly without an if check is rejected.
3. Exhaustive Check with never
If you add a new variant to Event but forget to add a case in the switch, e is no longer never, so the _exhaustive: never assignment fails to compile — you catch the missing handler at compile time.
4. throw vs Result — When to Use Which?
throw is for 'abnormal' conditions; Result is for 'expected failures'.
💡 💡 Result Pattern Practical Guide
1. Build Result without a library — 30 lines is all you need
2. Classify errors with Discriminated Union as well
Attach the exact additional information (field · max) to the right variant for each error kind.
3. Force exhaustive check with never
4. The boundary between Result and throw
Predictable failures (validation failure · 404 · authentication) → Result. Unpredictable bugs (null pointer · OOM) → throw + global handler.
5. async + Result
Expected failures go through Result; unexpected errors are re-thrown.