Glossary / Custom exception design
Custom exception design
Custom exceptions define domain-specific failure types that callers can catch when they need a distinct recovery or translation policy. They should represent exceptional conditions, preserve meaningful context, and avoid creating a new class for every message or ordinary validation outcome.
Type design
Derive from Exception (or an appropriate framework exception when semantics match). Provide a clear name ending in Exception, stable properties for machine-readable context, and constructors that support message and inner exception. Historically serializable exception patterns were recommended for .NET Framework remoting; modern .NET generally does not require formatter serialization and obsolete serialization APIs should not be copied blindly.
public sealed class OrderNotFoundException : Exception
{
public Guid OrderId { get; }
public OrderNotFoundException(Guid id)
: base($"Order {id} was not found.") => OrderId = id;
}
Do not encode state only in message text; messages are for humans and can change or be localized. Preserve the causal exception when wrapping. Make exceptions serializable only when a real supported serialization scenario requires it, using current platform guidance.
API and operational guidance
Throw custom exceptions when callers can act differently based on the type or stable properties. Use validation/result types for expected outcomes where exceptions would be routine. Avoid leaking sensitive identifiers or secrets in messages. Document which exceptions public methods may throw and define retryability separately from exception naming.
Interview questions
- When create a custom exception? When a distinct domain failure enables meaningful caller handling.
- Why not parse messages? Text is unstable and intended for humans, not machine contracts.
- Why preserve InnerException? It retains the root cause and diagnostic stack.
- Should all validation failures throw? No; expected invalid input may be clearer as validation results or
Trymethods. - Should modern custom exceptions add binary serialization constructors? Only for a real supported need; old formatter patterns are obsolete in modern .NET.