Roadmap › Exception Handling & Custom Error Handling in .NET — Every Way, Every App Type › Module: Exceptions in C#
Lessons in this course (9)
3. Exceptions vs the Result pattern
Intermediate★ Must knowLesson 3 of 9
| Exceptions | Result object | |
|---|---|---|
| Signal | throw | return Result.Fail("...") |
| Visible in signature | No | Yes (Result<Order>) |
| Cost | Expensive (stack trace) | Cheap |
| Forgetting to handle | Bubbles to global handler | Compiler doesn't force checking unless designed so |
| Good for | Unexpected/exceptional failures, invariants broken | Expected outcomes: validation failed, not found, rule violated |
csharp
public readonly record struct Result<T>(T? Value, string? Error)
{
public bool IsSuccess => Error is null;
public static Result<T> Ok(T value) => new(value, null);
public static Result<T> Fail(string error) => new(default, error);
}
public Result<Order> PlaceOrder(Cart cart)
{
if (cart.Items.Count == 0) return Result<Order>.Fail("Cart is empty");
return Result<Order>.Ok(new Order(cart));
}
// Controller maps results to HTTP
var result = service.PlaceOrder(cart);
return result.IsSuccess ? Ok(result.Value) : BadRequest(new { error = result.Error });Many teams combine: Result for validation/business outcomes, exceptions for truly exceptional problems (database down, bug).