TaskHub.Shared.Domain uses a structured approach to handling business logic errors, distinguishing them from infrastructure or technical exceptions.
Instead of using plain strings for error messages, we use DomainErrorBase (a record) to encapsulate error metadata.
public abstract record DomainErrorBase(int Code, string Domain, string Description);
Applications should define their domain errors as static members:
public static class ProjectErrors
{
public static readonly DomainErrorBase InvalidName =
new(400, "Project", "Project name cannot be empty.");
public static readonly DomainErrorBase ProjectFull =
new(409, "Project", "Project has reached the maximum number of tasks.");
}
When a domain invariant is violated, a DomainException is thrown. This exception carries the DomainErrorBase.
public class DomainException(DomainErrorBase errorCode) : Exception(errorCode.Description)
{
public DomainErrorBase ErrorCode { get; } = errorCode;
}
Result with the appropriate ResultCode.IPreBehavior and fluent validation for basic input checks. Save DomainException for complex business rule violations that require state knowledge.DomainErrorBase instances for each unique error scenario.Description can be used as a key for localized error messages in the UI layer.