error-handlinglisted
Install: claude install-skill zdanovichnick/dotnet-pilot
# Error Handling Patterns
Reference for structured error handling in .NET APIs. Used by `dnp-planner`, `dnp-api-scaffolder`, and `dnp-tdd-developer-hard`.
## Philosophy: When to Use Results vs Exceptions
| Scenario | Approach |
|----------|----------|
| Domain rule violation (not found, invalid state, business constraint) | `Result<TValue, TError>` — expected failure path |
| Infrastructure failure (DB timeout, network error, config missing) | Exception — unexpected, unrecoverable at call site |
| Validation failure (bad input from HTTP layer) | `ValidationProblemDetails` via model binding / FluentValidation |
| Unhandled exception escaping to HTTP | `GlobalExceptionHandler` → 500 ProblemDetails |
Never throw exceptions for expected domain outcomes. Never swallow exceptions at call sites.
## Result Type
Define in a shared location (e.g., `Common/Result.cs`):
```csharp
namespace MyApp.Common;
public readonly record struct Result<TValue, TError>
{
private readonly TValue? _value;
private readonly TError? _error;
public bool IsSuccess { get; }
public bool IsFailure => !IsSuccess;
private Result(TValue value) { _value = value; IsSuccess = true; }
private Result(TError error) { _error = error; IsSuccess = false; }
public static Result<TValue, TError> Success(TValue value) => new(value);
public static Result<TValue, TError> Failure(TError error) => new(error);
public TResult Match<TResult>(
Func<TValue, TResult> onSuccess,