Skip to content

Error System Specification

Functorium’s error system consists of per-layer sealed record hierarchies (DomainErrorType, ApplicationErrorType, AdapterErrorType) and per-layer factories (DomainError, ApplicationError, EventError, AdapterError). Common creation logic for the factories is centralized in the internal LayerErrorCore, and common overrides for Expected errors are consolidated in ErrorCodeExpectedBase. This specification defines the signatures, properties, and error code generation rules for public/internal types.

TypeNamespaceDescription
ErrorTypeFunctorium.Abstractions.ErrorsAbstract base record for all layer error types
IHasErrorCodeFunctorium.Abstractions.ErrorsError code access interface
ErrorCodeFactoryFunctorium.Abstractions.ErrorsExpected/Exceptional error creation factory
DomainErrorTypeFunctorium.Domains.ErrorsDomain error type sealed record hierarchy (10 categories)
DomainErrorFunctorium.Domains.ErrorsDomain error creation factory
ApplicationErrorTypeFunctorium.Applications.ErrorsApplication error type sealed record hierarchy (14 types)
ApplicationErrorFunctorium.Applications.ErrorsApplication error creation factory
EventErrorTypeFunctorium.Applications.ErrorsEvent error type sealed record hierarchy (4 types)
EventErrorFunctorium.Applications.ErrorsEvent error creation factory
AdapterErrorTypeFunctorium.Adapters.ErrorsAdapter error type sealed record hierarchy (20 types)
AdapterErrorFunctorium.Adapters.ErrorsAdapter error creation factory
TypeNamespaceDescription
ErrorCodeExpectedBaseFunctorium.Abstractions.ErrorsBase class for common LanguageExt Error overrides of 4 Expected error types
ErrorCodeExpected (4 types)Functorium.Abstractions.ErrorsExpected errors — responsible only for value storage, inheriting the rest from base
ErrorCodeExceptionalFunctorium.Abstractions.ErrorsWraps Exception with error code
LayerErrorCoreFunctorium.Abstractions.ErrorsCommon error code creation logic for all 4 layer factories
ErrorAssertionCoreFunctorium.Testing.Assertions.ErrorsCommon validation logic for 3 layer Assertions

All error codes follow this pattern:

{LayerPrefix}.{ContextName}.{ErrorName}
LayerPrefixExample
DomainDomainErrorsDomainErrors.Email.Empty
ApplicationApplicationErrorsApplicationErrors.CreateProductCommand.AlreadyExists
AdapterAdapterErrorsAdapterErrors.ProductRepository.NotFound

namespace Functorium.Abstractions.Errors;
public abstract record ErrorType
{
public const string DomainErrorsPrefix = "DomainErrors";
public const string ApplicationErrorsPrefix = "ApplicationErrors";
public const string AdapterErrorsPrefix = "AdapterErrors";
public virtual string ErrorName => GetType().Name;
}

ErrorType is the common base for all per-layer error types (DomainErrorType, ApplicationErrorType, AdapterErrorType).

MemberKindDescription
DomainErrorsPrefixconst stringDomain error code prefix "DomainErrors"
ApplicationErrorsPrefixconst stringApplication error code prefix "ApplicationErrors"
AdapterErrorsPrefixconst stringAdapter error code prefix "AdapterErrors"
ErrorNamevirtual stringLast segment of the error code. Defaults to GetType().Name
namespace Functorium.Abstractions.Errors;
public interface IHasErrorCode
{
string ErrorCode { get; }
}

IHasErrorCode is an interface for type-safe error code access without reflection. ErrorCodeExpected and ErrorCodeExceptional implement this interface.


internal abstract record ErrorCodeExpectedBase(
string ErrorCode,
string ErrorMessage,
int ErrorCodeId = -1000,
Option<Error> Inner = default) : Error, IHasErrorCode

ErrorCodeExpectedBase is the common base class for the 4 Expected error types (ErrorCodeExpected, <T>, <T1,T2>, <T1,T2,T3>). It defines all 13 LanguageExt Error overrides in one place, eliminating duplication in derived types.

MemberKindDescription
ErrorCodestringError code in "{Prefix}.{Context}.{ErrorName}" format
Messageoverride stringHuman-readable error message
Codeoverride intInteger error code ID (default -1000)
Inneroverride Option<Error>Inner error (default None)
ToString()sealed overrideReturns Message. sealed prevents auto-generation by derived records
ToErrorException()overrideReturns WrappedErrorExpectedException
IsExpectedboolAlways true
IsExceptionalboolAlways false

sealed override ToString(): C# records auto-regenerate ToString() in derived classes. sealed blocks this to ensure all derived types consistently return Message.

internal record ErrorCodeExpected(
string ErrorCode,
string ErrorCurrentValue,
string ErrorMessage,
int ErrorCodeId = -1000,
Option<Error> Inner = default)
: ErrorCodeExpectedBase(ErrorCode, ErrorMessage, ErrorCodeId, Inner)

ErrorCodeExpected represents expected errors such as business rule violations. It inherits common members (ErrorCode, Message, Code, Inner, ToString(), IsExpected, IsExceptional) from ErrorCodeExpectedBase, and derived types only add the value at error time (ErrorCurrentValue).

OverloadAdditional PropertiesDescription
ErrorCodeExpectedErrorCurrentValue: stringString value
ErrorCodeExpected<T>ErrorCurrentValue: TTyped value (1)
ErrorCodeExpected<T1, T2>ErrorCurrentValue1: T1, ErrorCurrentValue2: T2Typed values (2)
ErrorCodeExpected<T1, T2, T3>ErrorCurrentValue1: T1, ErrorCurrentValue2: T2, ErrorCurrentValue3: T3Typed values (3)
internal record ErrorCodeExceptional : Error, IHasErrorCode
{
public ErrorCodeExceptional(string errorCode, Exception exception);
}

ErrorCodeExceptional wraps a system Exception with an error code. IsExpected = false, IsExceptional = true.

PropertyTypeDescription
ErrorCodestringError code in "{Prefix}.{Context}.{ErrorName}" format
MessagestringExtracted from exception.Message
CodeintExtracted from exception.HResult
InnerOption<Error>Recursively wraps InnerException if present
IsExpectedboolAlways false
IsExceptionalboolAlways true
namespace Functorium.Abstractions.Errors;
public static class ErrorCodeFactory
{
// Expected error creation
public static Error Create(string errorCode, string errorCurrentValue, string errorMessage);
public static Error Create<T>(string errorCode, T errorCurrentValue, string errorMessage) where T : notnull;
public static Error Create<T1, T2>(string errorCode, T1 errorCurrentValue1, T2 errorCurrentValue2, string errorMessage)
where T1 : notnull where T2 : notnull;
public static Error Create<T1, T2, T3>(string errorCode, T1 errorCurrentValue1, T2 errorCurrentValue2, T3 errorCurrentValue3, string errorMessage)
where T1 : notnull where T2 : notnull where T3 : notnull;
// Exceptional error creation
public static Error CreateFromException(string errorCode, Exception exception);
// Error code composition
public static string Format(params string[] parts);
}

ErrorCodeFactory is a static factory that creates ErrorCodeExpected and ErrorCodeExceptional instances. Per-layer factories create errors through the following flow:

DomainError.For<T>(DomainErrorType, ...) <- Layer type safety (public API)
-> LayerErrorCore.Create<T>(prefix, ErrorType, ...) <- Common error code assembly (internal)
-> ErrorCodeFactory.Create(errorCode, ...) <- ErrorCodeExpected instance creation (internal)

LayerErrorCore assembles the error code string ({Prefix}.{Context}.{ErrorName}), and ErrorCodeFactory creates the final Error instance. [AggressiveInlining] is applied to all methods so the JIT eliminates delegation calls, resulting in no performance difference.

MethodReturnDescription
Create(...)ErrorCreates Expected error (4 overloads)
CreateFromException(...)ErrorWraps Exception as Exceptional error
Format(...)stringJoins string array with '.' to generate error code

namespace Functorium.Domains.Errors;
public abstract partial record DomainErrorType : ErrorType;

DomainErrorType is the sealed record hierarchy base for domain layer errors. Classified into 10 categories.

sealed recordPropertiesDescription
NotFound(none)Value not found
AlreadyExists(none)Value already exists
Duplicate(none)Duplicate value
Mismatch(none)Value mismatch (e.g., password confirmation)
public sealed record NotFound : DomainErrorType;
public sealed record AlreadyExists : DomainErrorType;
public sealed record Duplicate : DomainErrorType;
public sealed record Mismatch : DomainErrorType;
sealed recordPropertiesDescription
Empty(none)Value is empty (null, empty string, empty collection, etc.)
Null(none)Value is null
public sealed record Empty : DomainErrorType;
public sealed record Null : DomainErrorType;
sealed recordPropertiesDescription
InvalidFormatstring? PatternValue format is invalid. Pattern is the expected format pattern
NotUpperCase(none)Value is not uppercase
NotLowerCase(none)Value is not lowercase
public sealed record InvalidFormat(string? Pattern = null) : DomainErrorType;
public sealed record NotUpperCase : DomainErrorType;
public sealed record NotLowerCase : DomainErrorType;
sealed recordPropertiesDescription
TooShortint MinLengthValue is shorter than minimum length. Default 0 (unspecified)
TooLongint MaxLengthValue exceeds maximum length. Default int.MaxValue (unspecified)
WrongLengthint ExpectedValue length does not match expected. Default 0 (unspecified)
public sealed record TooShort(int MinLength = 0) : DomainErrorType;
public sealed record TooLong(int MaxLength = int.MaxValue) : DomainErrorType;
public sealed record WrongLength(int Expected = 0) : DomainErrorType;
sealed recordPropertiesDescription
Zero(none)Value is zero
Negative(none)Value is negative
NotPositive(none)Value is not positive (zero or negative)
OutOfRangestring? Min, string? MaxValue is outside allowed range
BelowMinimumstring? MinimumValue is below minimum
AboveMaximumstring? MaximumValue exceeds maximum
public sealed record Zero : DomainErrorType;
public sealed record Negative : DomainErrorType;
public sealed record NotPositive : DomainErrorType;
public sealed record OutOfRange(string? Min = null, string? Max = null) : DomainErrorType;
public sealed record BelowMinimum(string? Minimum = null) : DomainErrorType;
public sealed record AboveMaximum(string? Maximum = null) : DomainErrorType;
sealed recordPropertiesDescription
DefaultDate(none)Date is default value (DateTime.MinValue)
NotInPast(none)Date should be in the past but is in the future
NotInFuture(none)Date should be in the future but is in the past
TooLatestring? BoundaryDate is after the boundary (should be before)
TooEarlystring? BoundaryDate is before the boundary (should be after)
public sealed record DefaultDate : DomainErrorType;
public sealed record NotInPast : DomainErrorType;
public sealed record NotInFuture : DomainErrorType;
public sealed record TooLate(string? Boundary = null) : DomainErrorType;
public sealed record TooEarly(string? Boundary = null) : DomainErrorType;
sealed recordPropertiesDescription
RangeInvertedstring? Min, string? MaxRange is inverted (minimum greater than maximum)
RangeEmptystring? ValueRange is empty (minimum equals maximum)
public sealed record RangeInverted(string? Min = null, string? Max = null) : DomainErrorType;
public sealed record RangeEmpty(string? Value = null) : DomainErrorType;
sealed recordPropertiesDescription
InvalidTransitionstring? FromState, string? ToStateInvalid state transition (e.g., Paid -> Active)
public sealed record InvalidTransition(string? FromState = null, string? ToState = null) : DomainErrorType;

Records the pre- and post-transition states via FromState and ToState. Preserves transition information as structured data independent of the error message, enabling use in logging/monitoring.

public abstract record Custom : DomainErrorType;

Custom is the base class for domain-specific errors that cannot be expressed with standard error types. Define derived sealed records to use.

// Define as a nested record inside an Entity
public sealed record InsufficientStock : DomainErrorType.Custom;
DomainError.For<Inventory>(new InsufficientStock(), currentStock, "Insufficient stock");
// Error code: DomainErrors.Inventory.InsufficientStock

namespace Functorium.Applications.Errors;
public abstract record ApplicationErrorType : ErrorType;

ApplicationErrorType is the sealed record hierarchy base for application layer errors.

sealed recordPropertiesDescription
Empty(none)Value is empty
Null(none)Value is null
NotFound(none)Value not found
AlreadyExists(none)Value already exists
Duplicate(none)Duplicate value
InvalidState(none)Invalid state
Unauthorized(none)Not authenticated
Forbidden(none)Access forbidden
public sealed record Empty : ApplicationErrorType;
public sealed record Null : ApplicationErrorType;
public sealed record NotFound : ApplicationErrorType;
public sealed record AlreadyExists : ApplicationErrorType;
public sealed record Duplicate : ApplicationErrorType;
public sealed record InvalidState : ApplicationErrorType;
public sealed record Unauthorized : ApplicationErrorType;
public sealed record Forbidden : ApplicationErrorType;
sealed recordPropertiesDescription
ValidationFailedstring? PropertyNameValidation failed. PropertyName is the failed property name
public sealed record ValidationFailed(string? PropertyName = null) : ApplicationErrorType;
sealed recordPropertiesDescription
BusinessRuleViolatedstring? RuleNameBusiness rule violated. RuleName is the violated rule name
ConcurrencyConflict(none)Concurrency conflict
ResourceLockedstring? ResourceNameResource locked. ResourceName is the locked resource name
OperationCancelled(none)Operation cancelled
InsufficientPermissionstring? PermissionInsufficient permission. Permission is the required permission
public sealed record BusinessRuleViolated(string? RuleName = null) : ApplicationErrorType;
public sealed record ConcurrencyConflict : ApplicationErrorType;
public sealed record ResourceLocked(string? ResourceName = null) : ApplicationErrorType;
public sealed record OperationCancelled : ApplicationErrorType;
public sealed record InsufficientPermission(string? Permission = null) : ApplicationErrorType;
public abstract record Custom : ApplicationErrorType;
// Usage example
public sealed record CannotProcess : ApplicationErrorType.Custom;
namespace Functorium.Applications.Errors;
public abstract record EventErrorType : ErrorType;

EventErrorType is the error type for domain event publishing/handling errors.

sealed recordPropertiesDescription
PublishFailed(none)Event publish failed
HandlerFailed(none)Event handler execution failed
InvalidEventType(none)Event type is invalid
PublishCancelled(none)Event publish cancelled
public sealed record PublishFailed : EventErrorType;
public sealed record HandlerFailed : EventErrorType;
public sealed record InvalidEventType : EventErrorType;
public sealed record PublishCancelled : EventErrorType;

Custom extension:

public abstract record Custom : EventErrorType;
// Usage example
public sealed record RetryExhausted : EventErrorType.Custom;

namespace Functorium.Adapters.Errors;
public abstract record AdapterErrorType : ErrorType;

AdapterErrorType is the sealed record hierarchy base for adapter layer errors.

sealed recordPropertiesDescription
Empty(none)Value is empty
Null(none)Value is null
NotFound(none)Value not found
PartialNotFound(none)Some of the requested IDs were not found
AlreadyExists(none)Value already exists
Duplicate(none)Duplicate value
InvalidState(none)Invalid state
NotConfigured(none)Required configuration is missing
NotSupported(none)Unsupported operation
Unauthorized(none)Not authenticated
Forbidden(none)Access forbidden
public sealed record Empty : AdapterErrorType;
public sealed record Null : AdapterErrorType;
public sealed record NotFound : AdapterErrorType;
public sealed record PartialNotFound : AdapterErrorType;
public sealed record AlreadyExists : AdapterErrorType;
public sealed record Duplicate : AdapterErrorType;
public sealed record InvalidState : AdapterErrorType;
public sealed record NotConfigured : AdapterErrorType;
public sealed record NotSupported : AdapterErrorType;
public sealed record Unauthorized : AdapterErrorType;
public sealed record Forbidden : AdapterErrorType;
sealed recordPropertiesDescription
PipelineValidationstring? PropertyNamePipeline validation failed. PropertyName is the failed property name
PipelineException(none)Pipeline exception occurred
public sealed record PipelineValidation(string? PropertyName = null) : AdapterErrorType;
public sealed record PipelineException : AdapterErrorType;
sealed recordPropertiesDescription
ExternalServiceUnavailablestring? ServiceNameExternal service unavailable. ServiceName is the service name
ConnectionFailedstring? TargetConnection failed. Target is the connection target
TimeoutTimeSpan? DurationTimeout. Duration is the timeout duration
public sealed record ExternalServiceUnavailable(string? ServiceName = null) : AdapterErrorType;
public sealed record ConnectionFailed(string? Target = null) : AdapterErrorType;
public sealed record Timeout(TimeSpan? Duration = null) : AdapterErrorType;
sealed recordPropertiesDescription
Serializationstring? FormatSerialization failed. Format is the serialization format
Deserializationstring? FormatDeserialization failed. Format is the deserialization format
DataCorruption(none)Data corruption
public sealed record Serialization(string? Format = null) : AdapterErrorType;
public sealed record Deserialization(string? Format = null) : AdapterErrorType;
public sealed record DataCorruption : AdapterErrorType;
public abstract record Custom : AdapterErrorType;
// Usage example
public sealed record RateLimited : AdapterErrorType.Custom;

namespace Functorium.Abstractions.Errors;
internal static class LayerErrorCore
{
internal static Error Create<TContext>(string prefix, ErrorType errorType, string currentValue, string message);
internal static Error Create<TContext, TValue>(string prefix, ErrorType errorType, TValue currentValue, string message)
where TValue : notnull;
internal static Error Create<TContext, T1, T2>(...) where T1 : notnull where T2 : notnull;
internal static Error Create<TContext, T1, T2, T3>(...) where T1 : notnull where T2 : notnull where T3 : notnull;
internal static Error Create(string prefix, Type contextType, ErrorType errorType, string currentValue, string message);
internal static Error ForContext(string prefix, string contextName, ErrorType errorType, string currentValue, string message);
internal static Error ForContext<TValue>(string prefix, string contextName, ErrorType errorType, TValue currentValue, string message)
where TValue : notnull;
internal static Error FromException<TContext>(string prefix, ErrorType errorType, Exception exception);
}

LayerErrorCore is the common implementation for the 4 layer factories (DomainError, ApplicationError, EventError, AdapterError). It assembles the error code string {prefix}.{typeof(TContext).Name}.{errorType.ErrorName} and delegates to ErrorCodeFactory.

Design principle: Public factories maintain per-layer type parameters (DomainErrorType, ApplicationErrorType, etc.) to ensure compile-time safety. LayerErrorCore receives the base type ErrorType to eliminate implementation duplication. [AggressiveInlining] is applied to all methods so the JIT inlines delegation calls.

// Compile-time safety example
DomainError.For<Email>(new DomainErrorType.Empty(), ...) // Compiles OK
DomainError.For<Email>(new AdapterErrorType.Timeout(), ...) // CS1503
namespace Functorium.Testing.Assertions.Errors;
internal static class ErrorAssertionCore
{
// Error -- ErrorCode validation, value validation (1~3), Exceptional validation
internal static void ShouldBeError<TContext>(Error error, string prefix, string errorName);
internal static void ShouldBeError<TContext, TValue>(Error error, string prefix, string errorName, TValue expectedValue);
internal static void ShouldBeExceptionalError<TContext>(Error error, string prefix, string errorName);
// Fin<T> -- failure state + ErrorCode validation
internal static void ShouldBeFinError<TContext, T>(Fin<T> fin, string prefix, string errorName);
// Validation<Error, T> -- error contains/only/multiple validation
internal static void ShouldHaveError<TContext, T>(Validation<Error, T> validation, string prefix, string errorName);
internal static void ShouldHaveOnlyError<TContext, T>(Validation<Error, T> validation, string prefix, string errorName);
internal static void ShouldHaveErrors<TContext, T>(Validation<Error, T> validation, string prefix, params string[] errorNames);
}

ErrorAssertionCore is the common validation logic for the 3 layer Assertions (DomainErrorAssertions, ApplicationErrorAssertions, AdapterErrorAssertions). It provides error code assembly ({prefix}.{typeof(TContext).Name}.{errorName}), ErrorCodeExpected<T> type casting, and value comparison. Per-layer Assertions are thin wrappers that bind only the prefix and error type.


namespace Functorium.Domains.Errors;
public static class DomainError
{
public static Error For<TDomain>(DomainErrorType errorType, string currentValue, string message);
public static Error For<TDomain, TValue>(DomainErrorType errorType, TValue currentValue, string message)
where TValue : notnull;
public static Error For<TDomain, T1, T2>(DomainErrorType errorType, T1 value1, T2 value2, string message)
where T1 : notnull where T2 : notnull;
public static Error For<TDomain, T1, T2, T3>(DomainErrorType errorType, T1 value1, T2 value2, T3 value3, string message)
where T1 : notnull where T2 : notnull where T3 : notnull;
}

Error code format: DomainErrors.{typeof(TDomain).Name}.{errorType.ErrorName}

OverloadValue ParametersDescription
For<TDomain>(...)string currentValueDefault string value
For<TDomain, TValue>(...)TValue currentValueGeneric single value
For<TDomain, T1, T2>(...)T1 value1, T2 value2Generic 2 values
For<TDomain, T1, T2, T3>(...)T1 value1, T2 value2, T3 value3Generic 3 values

Usage examples:

using static Functorium.Domains.Errors.DomainErrorType;
// Basic usage
DomainError.For<Email>(new Empty(), "", "Email cannot be empty");
// Error code: DomainErrors.Email.Empty
// Error type with properties
DomainError.For<Password>(new TooShort(MinLength: 8), value, "Password is too short");
// Error code: DomainErrors.Password.TooShort
// State transition error
DomainError.For<Order>(new InvalidTransition(FromState: "Paid", ToState: "Active"), orderId, "Invalid state transition");
// Error code: DomainErrors.Order.InvalidTransition
// Custom error
DomainError.For<Currency>(new Unsupported(), value, "Unsupported currency");
// Error code: DomainErrors.Currency.Unsupported
namespace Functorium.Applications.Errors;
public static class ApplicationError
{
public static Error For<TUsecase>(ApplicationErrorType errorType, string currentValue, string message);
public static Error For<TUsecase, TValue>(ApplicationErrorType errorType, TValue currentValue, string message)
where TValue : notnull;
public static Error For<TUsecase, T1, T2>(ApplicationErrorType errorType, T1 value1, T2 value2, string message)
where T1 : notnull where T2 : notnull;
public static Error For<TUsecase, T1, T2, T3>(ApplicationErrorType errorType, T1 value1, T2 value2, T3 value3, string message)
where T1 : notnull where T2 : notnull where T3 : notnull;
}

Error code format: ApplicationErrors.{typeof(TUsecase).Name}.{errorType.ErrorName}

Usage examples:

ApplicationErrors.CreateProductCommand.AlreadyExists
using static Functorium.Applications.Errors.ApplicationErrorType;
ApplicationError.For<CreateProductCommand>(new AlreadyExists(), productId, "Already exists");
ApplicationError.For<UpdateOrderCommand>(new ValidationFailed("Quantity"), value, "Quantity must be positive");
// Error code: ApplicationErrors.UpdateOrderCommand.ValidationFailed
namespace Functorium.Applications.Errors;
public static class EventError
{
public static Error For<TPublisher>(EventErrorType errorType, string currentValue, string message);
public static Error For<TPublisher, TValue>(EventErrorType errorType, TValue currentValue, string message)
where TValue : notnull;
public static Error FromException<TPublisher>(Exception exception);
public static Error FromException<TPublisher>(EventErrorType errorType, Exception exception);
}

Error code format: ApplicationErrors.{typeof(TPublisher).Name}.{errorType.ErrorName}

EventError shares the ApplicationErrors prefix and represents event publishing/handling failures.

MethodDescription
For<TPublisher>(...)Creates Expected error
For<TPublisher, TValue>(...)Creates Expected error with generic value
FromException<TPublisher>(exception)Wraps exception as PublishFailed type Exceptional error
FromException<TPublisher>(errorType, exception)Wraps exception as specified type Exceptional error

Usage examples:

ApplicationErrors.DomainEventPublisher.PublishFailed
using static Functorium.Applications.Errors.EventErrorType;
EventError.For<DomainEventPublisher>(new PublishFailed(), eventType, "Event publishing failed");
EventError.FromException<DomainEventPublisher>(exception);
// Error code: ApplicationErrors.DomainEventPublisher.PublishFailed (Exceptional)
namespace Functorium.Adapters.Errors;
public static class AdapterError
{
public static Error For<TAdapter>(AdapterErrorType errorType, string currentValue, string message);
public static Error For(Type adapterType, AdapterErrorType errorType, string currentValue, string message);
public static Error For<TAdapter, TValue>(AdapterErrorType errorType, TValue currentValue, string message)
where TValue : notnull;
public static Error For<TAdapter, T1, T2>(AdapterErrorType errorType, T1 value1, T2 value2, string message)
where T1 : notnull where T2 : notnull;
public static Error For<TAdapter, T1, T2, T3>(AdapterErrorType errorType, T1 value1, T2 value2, T3 value3, string message)
where T1 : notnull where T2 : notnull where T3 : notnull;
public static Error FromException<TAdapter>(AdapterErrorType errorType, Exception exception);
}

Error code format: AdapterErrors.{typeof(TAdapter).Name}.{errorType.ErrorName}

OverloadValue ParametersDescription
For<TAdapter>(...)string currentValueDefault string value
For(Type, ...)string currentValueSpecifies adapter via runtime Type (for GetType() in base classes)
For<TAdapter, TValue>(...)TValue currentValueGeneric single value
For<TAdapter, T1, T2>(...)T1 value1, T2 value2Generic 2 values
For<TAdapter, T1, T2, T3>(...)T1 value1, T2 value2, T3 value3Generic 3 values
FromException<TAdapter>(...)Exception exceptionWraps Exception as Exceptional error

Usage examples:

using static Functorium.Adapters.Errors.AdapterErrorType;
// Expected error
AdapterError.For<ProductRepository>(new NotFound(), id, "Product not found");
// Error code: AdapterErrors.ProductRepository.NotFound
// Pipeline error
AdapterError.For<UsecaseValidationPipeline>(new PipelineValidation("PropertyName"), value, "Validation failed");
// Error code: AdapterErrors.UsecaseValidationPipeline.PipelineValidation
// Exception wrapping
AdapterError.FromException<UsecaseExceptionPipeline>(new PipelineException(), exception);
// Error code: AdapterErrors.UsecaseExceptionPipeline.PipelineException (Exceptional)
// Runtime Type usage
AdapterError.For(GetType(), new ConnectionFailed("DB"), connectionString, "Connection failed");
// Error code: AdapterErrors.{ActualTypeName}.ConnectionFailed

DocumentDescription
Error System: Fundamentals and NamingError handling principles, Fin patterns, naming rules R1~R8
Error System: Domain/Application/EventDomain, Application, Event error detailed guide
Error System: Adapter and TestingAdapter error and test pattern guide
Validation System SpecificationTypedValidation, ContextualValidation specification